agentic-qe 3.11.5 → 3.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/helpers/.helpers-version +1 -0
- package/.claude/helpers/auto-memory-hook.mjs +35 -3
- package/.claude/helpers/brain-checkpoint.cjs +16 -1
- package/.claude/helpers/helpers.manifest.json +12 -0
- package/.claude/helpers/hook-handler.cjs +26 -5
- package/.claude/helpers/intelligence.cjs +14 -1
- package/.claude/hooks/aqe-hook.cjs +14 -1
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +87 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/adapters/a2a/auth/routes.js +59 -28
- package/dist/cli/bundle.js +6 -6
- package/dist/cli/chunks/adapter-X4UEC6UJ.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-CSTBLNYZ.js → agent-booster-wasm-P4VYM5KK.js} +2 -2
- package/dist/cli/chunks/{agent-handler-M4W4GTXN.js → agent-handler-PBQ7L2TO.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-VGXFYLSQ.js → agent-memory-branch-UPWO3X6V.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-5FG7JCY7.js +2 -0
- package/dist/cli/chunks/{arena-IQBRGWAG.js → arena-LEUTILZ7.js} +2 -2
- package/dist/cli/chunks/{arena-FKSD3LLM.js → arena-QYTP3FG6.js} +4 -4
- package/dist/cli/chunks/{audit-7NSGRR4Z.js → audit-TB6M2YLK.js} +3 -3
- package/dist/cli/chunks/base-CWPMFSZG.js +2 -0
- package/dist/cli/chunks/{hnswlib-node-E6NSZPP2.js → better-sqlite3-IPKCAVLS.js} +2 -2
- package/dist/cli/chunks/{brain-handler-M6A3UB66.js → brain-handler-JF3OK35F.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-2JGKY4BB.js → branch-enumerator-WEIP3DXB.js} +2 -2
- package/dist/cli/chunks/{browser-J43WQPJL.js → browser-HY6VLXHZ.js} +2 -2
- package/dist/cli/chunks/browser-workflow-A77OFBVY.js +2 -0
- package/dist/cli/chunks/{chunk-7BCRULCP.js → chunk-2PQ7YADF.js} +2 -2
- package/dist/cli/chunks/{chunk-XKQY2Z3Q.js → chunk-3I3Z4C5X.js} +1 -1
- package/dist/cli/chunks/{chunk-MCHEUSY4.js → chunk-3W2FZXFD.js} +1 -1
- package/dist/cli/chunks/{chunk-WMZ2QGGS.js → chunk-42GFB7VX.js} +2 -2
- package/dist/cli/chunks/{chunk-UBI2EOS3.js → chunk-42PYEEYQ.js} +1 -1
- package/dist/cli/chunks/{chunk-HJWT4KME.js → chunk-45QNHMTP.js} +1 -1
- package/dist/cli/chunks/{chunk-AGJOGUP5.js → chunk-4KI72C2E.js} +1 -1
- package/dist/cli/chunks/{chunk-5WMU7XCF.js → chunk-4LKQZW2H.js} +1 -1
- package/dist/cli/chunks/{chunk-SUL3I6QZ.js → chunk-4U5MJX2H.js} +2 -2
- package/dist/cli/chunks/{chunk-DFRRWOEX.js → chunk-55MQ2SFP.js} +2 -2
- package/dist/cli/chunks/{chunk-KP3R2M2G.js → chunk-5H5A74U2.js} +1 -1
- package/dist/cli/chunks/{chunk-YBPLJRVT.js → chunk-5HMGDB7B.js} +2 -2
- package/dist/cli/chunks/{chunk-YZSTZUGJ.js → chunk-6432JORM.js} +1 -1
- package/dist/cli/chunks/{chunk-CDJP6COA.js → chunk-6BCVKCG5.js} +2 -2
- package/dist/cli/chunks/{chunk-TBT3OFRW.js → chunk-6ONUCDVL.js} +2 -2
- package/dist/cli/chunks/{chunk-3LY7OCSO.js → chunk-6RX5QZMU.js} +1 -1
- package/dist/cli/chunks/chunk-74VIADSJ.js +2 -0
- package/dist/cli/chunks/{chunk-K4I7UIU5.js → chunk-75AVUS5U.js} +1 -1
- package/dist/cli/chunks/{chunk-KVVJVMDM.js → chunk-774X6OJY.js} +2 -2
- package/dist/cli/chunks/chunk-7KHIOWBN.js +2 -0
- package/dist/cli/chunks/{chunk-62OTU2AP.js → chunk-7KK6XSYK.js} +2 -2
- package/dist/cli/chunks/{chunk-RFLHPLET.js → chunk-7N2SCRWJ.js} +1 -1
- package/dist/cli/chunks/{chunk-OS2HHJTM.js → chunk-AGWKCY42.js} +2 -2
- package/dist/cli/chunks/chunk-BAHXVVX3.js +4 -0
- package/dist/cli/chunks/{chunk-6T65OKUM.js → chunk-BALFQQB7.js} +2 -2
- package/dist/cli/chunks/{chunk-I3ANRYQ6.js → chunk-BBNQDHGF.js} +2 -2
- package/dist/cli/chunks/{chunk-LOE2JETO.js → chunk-BCBITOMT.js} +2 -2
- package/dist/cli/chunks/{chunk-FII3WCCY.js → chunk-BKKJEKNT.js} +2 -2
- package/dist/cli/chunks/{chunk-TTJJ4DQE.js → chunk-BLU7OLQZ.js} +2 -2
- package/dist/cli/chunks/{chunk-AL5VJJN4.js → chunk-BNMV5DCM.js} +1 -1
- package/dist/cli/chunks/{chunk-4XJ2A3HY.js → chunk-BPM7NEHS.js} +4 -4
- package/dist/cli/chunks/{chunk-3V36WMIO.js → chunk-BWNMAXV7.js} +1 -1
- package/dist/cli/chunks/{chunk-EDOGRFAG.js → chunk-BXIJY6SB.js} +1 -1
- package/dist/cli/chunks/{chunk-ZXEWTZFR.js → chunk-C2K4LQI5.js} +1 -1
- package/dist/cli/chunks/{chunk-3WR35GFF.js → chunk-C7HGYLNF.js} +2 -2
- package/dist/cli/chunks/{chunk-7YSBATSN.js → chunk-CDVKFAYP.js} +2 -2
- package/dist/cli/chunks/{chunk-JBKZ5TUM.js → chunk-CJTXZI37.js} +2 -2
- package/dist/cli/chunks/{chunk-VMWRMINE.js → chunk-CP4GSICY.js} +1 -1
- package/dist/cli/chunks/{chunk-2XPMATEK.js → chunk-CXUHD2O5.js} +2 -2
- package/dist/cli/chunks/{chunk-W7TYKPLY.js → chunk-CYYT6YEV.js} +2 -2
- package/dist/cli/chunks/{chunk-SO6G4IX3.js → chunk-D72N5V2S.js} +2 -2
- package/dist/cli/chunks/{chunk-4LODYRNV.js → chunk-DQ3J7ZT6.js} +2 -2
- package/dist/cli/chunks/{chunk-PVDXNQPL.js → chunk-DSNFOX22.js} +2 -2
- package/dist/cli/chunks/{chunk-LPR2R3AN.js → chunk-EOBZJDJR.js} +3 -3
- package/dist/cli/chunks/{chunk-6R3YOAKO.js → chunk-FBYFDD7L.js} +2 -2
- package/dist/cli/chunks/{chunk-ZPP57WQU.js → chunk-FFSS3Y6W.js} +2 -2
- package/dist/cli/chunks/chunk-FNMEVLSN.js +2 -0
- package/dist/cli/chunks/{chunk-7KXPNNMR.js → chunk-GASACVTU.js} +2 -2
- package/dist/cli/chunks/{chunk-ABU64UWB.js → chunk-GGF5FZWS.js} +1 -1
- package/dist/cli/chunks/{chunk-M6FW56MV.js → chunk-GLO53MUQ.js} +2 -2
- package/dist/cli/chunks/{chunk-52U5BFZP.js → chunk-GW3M7GQH.js} +2 -2
- package/dist/cli/chunks/chunk-GXMNCW2M.js +2 -0
- package/dist/cli/chunks/{chunk-D45QLJEL.js → chunk-HDI3FD4G.js} +1 -1
- package/dist/cli/chunks/{chunk-26WEI3P4.js → chunk-HGKSU4QV.js} +2 -2
- package/dist/cli/chunks/{chunk-B2VBDMDI.js → chunk-HHMTQQUE.js} +2 -2
- package/dist/cli/chunks/{chunk-4Y3LGBKJ.js → chunk-HZGFER4N.js} +3 -3
- package/dist/cli/chunks/{chunk-AXKWV5NF.js → chunk-I4BZLVFE.js} +3 -3
- package/dist/cli/chunks/{chunk-JDSHUECG.js → chunk-IC6SOVGO.js} +2 -2
- package/dist/cli/chunks/{chunk-YFCULQBP.js → chunk-IE6FDICX.js} +2 -2
- package/dist/cli/chunks/{chunk-FGD6HINU.js → chunk-IHWWZOHP.js} +1 -1
- package/dist/cli/chunks/{chunk-HC6KTVFR.js → chunk-J4IAMQZI.js} +2 -2
- package/dist/cli/chunks/{chunk-VMFAANWX.js → chunk-J6ZCULWG.js} +2 -2
- package/dist/cli/chunks/{chunk-YGVDP6X7.js → chunk-JDZIBSMY.js} +1 -1
- package/dist/cli/chunks/{chunk-WPSK237F.js → chunk-JIM4VSLF.js} +3 -3
- package/dist/cli/chunks/{chunk-EK3HPH6A.js → chunk-JRHRC2MP.js} +1 -1
- package/dist/cli/chunks/{chunk-3JF5A72M.js → chunk-JRNDFC23.js} +2 -2
- package/dist/cli/chunks/chunk-JWZNWVLG.js +153 -0
- package/dist/cli/chunks/{chunk-Q5TR6ETB.js → chunk-KQV5644J.js} +3 -3
- package/dist/cli/chunks/{chunk-4RTWPR3X.js → chunk-LAJHHR3Q.js} +1 -1
- package/dist/cli/chunks/{chunk-AOXJFDH5.js → chunk-LF5XOYR7.js} +10 -10
- package/dist/cli/chunks/{chunk-I3NWKPXJ.js → chunk-LRWBOJ5Y.js} +2 -2
- package/dist/cli/chunks/{chunk-354367AP.js → chunk-LZ6TJ7XL.js} +2 -2
- package/dist/cli/chunks/{chunk-4QOI5JS7.js → chunk-M5P5WNXA.js} +1 -1
- package/dist/cli/chunks/{chunk-SE3JFUKP.js → chunk-MCUILJ33.js} +1 -1
- package/dist/cli/chunks/{chunk-ZG5UAEEO.js → chunk-MIAY35K6.js} +2 -2
- package/dist/cli/chunks/{chunk-6Q57K4YD.js → chunk-N3PSRG6F.js} +2 -2
- package/dist/cli/chunks/{chunk-FMNXHVIN.js → chunk-NEXJUTHF.js} +2 -2
- package/dist/cli/chunks/{chunk-RJN2RM76.js → chunk-NHRBKOYD.js} +2 -2
- package/dist/cli/chunks/{chunk-BJLA2IX7.js → chunk-NK2Z6FGF.js} +2 -2
- package/dist/cli/chunks/{chunk-Y25PO65W.js → chunk-NOCPO55P.js} +2 -2
- package/dist/cli/chunks/{chunk-XT4TDLOB.js → chunk-NTMN2ZJY.js} +2 -2
- package/dist/cli/chunks/{chunk-7DTMENY6.js → chunk-NVXSM7UO.js} +2 -2
- package/dist/cli/chunks/{chunk-CKOF27L7.js → chunk-O65OPAZH.js} +2 -2
- package/dist/cli/chunks/{chunk-OGNTCZKK.js → chunk-OEXSBR72.js} +1 -1
- package/dist/cli/chunks/{chunk-Y6DWJKHU.js → chunk-OJORNYN3.js} +3 -3
- package/dist/cli/chunks/{chunk-DPL762HU.js → chunk-ONSNNY6J.js} +1 -1
- package/dist/cli/chunks/{chunk-IBDQWKI3.js → chunk-OXVAGR64.js} +2 -2
- package/dist/cli/chunks/{chunk-C5C4W572.js → chunk-P7G5LGUE.js} +2 -2
- package/dist/cli/chunks/{chunk-XLT3FYS7.js → chunk-PDS5P5QD.js} +2 -2
- package/dist/cli/chunks/{chunk-IU5RSN6M.js → chunk-PQ4NSXZM.js} +2 -2
- package/dist/cli/chunks/{chunk-4MHN7JWC.js → chunk-PRA73XZY.js} +12 -12
- package/dist/cli/chunks/{chunk-2XQHG56O.js → chunk-PZ3Q34OT.js} +2 -2
- package/dist/cli/chunks/{chunk-EEKG35K5.js → chunk-PZZDAECU.js} +3 -3
- package/dist/cli/chunks/{chunk-J6PFPY7V.js → chunk-QJXUK54J.js} +2 -2
- package/dist/cli/chunks/{chunk-7P6X4BFO.js → chunk-QOAI6ETC.js} +3 -3
- package/dist/cli/chunks/{chunk-53YOYZW5.js → chunk-QORWBION.js} +2 -2
- package/dist/cli/chunks/{chunk-OS62Y77J.js → chunk-QXZOUETY.js} +2 -2
- package/dist/cli/chunks/{chunk-G2ZIJZJ7.js → chunk-QZBPXJ5C.js} +2 -2
- package/dist/cli/chunks/{chunk-WHHQIL4F.js → chunk-R4A6PY5D.js} +2 -2
- package/dist/cli/chunks/{chunk-ZLBY25MB.js → chunk-R7XEACKR.js} +1 -1
- package/dist/cli/chunks/{chunk-K4C25BWV.js → chunk-RAS7WRN5.js} +2 -2
- package/dist/cli/chunks/{chunk-MHMQ6MCT.js → chunk-REJGZP27.js} +2 -2
- package/dist/cli/chunks/{chunk-PW72M2FE.js → chunk-RIASOMB2.js} +2 -2
- package/dist/cli/chunks/{chunk-TEIWJ3GJ.js → chunk-RJ7TU2MP.js} +1 -1
- package/dist/cli/chunks/{chunk-W72FJA2H.js → chunk-S42RFOZJ.js} +2 -2
- package/dist/cli/chunks/chunk-SFQFBLWQ.js +2 -0
- package/dist/cli/chunks/{chunk-O7J54OHN.js → chunk-SHKOPOPD.js} +1 -1
- package/dist/cli/chunks/{chunk-QKK7VBVB.js → chunk-TGIKKD43.js} +2 -2
- package/dist/cli/chunks/chunk-TMPRR3FZ.js +2 -0
- package/dist/cli/chunks/{chunk-GW6XWMX2.js → chunk-U55X2ZUM.js} +2 -2
- package/dist/cli/chunks/{chunk-C4EZNOWK.js → chunk-U5ITD7ZD.js} +1 -1
- package/dist/cli/chunks/{chunk-RKXZLTWR.js → chunk-UBPJQKYS.js} +2 -2
- package/dist/cli/chunks/{chunk-DVW66FPU.js → chunk-UBWSYDO5.js} +1 -1
- package/dist/cli/chunks/chunk-UEC53US3.js +316 -0
- package/dist/cli/chunks/{chunk-UBY322ED.js → chunk-UGPBL7LX.js} +2 -2
- package/dist/cli/chunks/{chunk-MMEXHZUC.js → chunk-UKF4V7LE.js} +5 -5
- package/dist/cli/chunks/{chunk-FIPKIIMS.js → chunk-UR655D4K.js} +2 -2
- package/dist/cli/chunks/{chunk-GODAWJMZ.js → chunk-USTUWUCE.js} +2 -2
- package/dist/cli/chunks/{chunk-FGSIID5C.js → chunk-UZXDYT6O.js} +2 -2
- package/dist/cli/chunks/{chunk-JATLFS6A.js → chunk-VFRWLSQO.js} +1 -1
- package/dist/cli/chunks/{chunk-AF6P5RWY.js → chunk-VHJCQBD2.js} +2 -2
- package/dist/cli/chunks/{chunk-J5XDKVI7.js → chunk-VTFYY4SH.js} +2 -2
- package/dist/cli/chunks/{chunk-BTLUWH4R.js → chunk-W52R3G22.js} +2 -2
- package/dist/cli/chunks/{chunk-AOQYORVA.js → chunk-WBDV4V3H.js} +2 -2
- package/dist/cli/chunks/{chunk-3I4TCMOJ.js → chunk-WPEGG6DX.js} +1 -1
- package/dist/cli/chunks/{chunk-KQVIWE3W.js → chunk-WPG5LXR7.js} +2 -2
- package/dist/cli/chunks/{chunk-DLBVADWQ.js → chunk-X2CEX4KC.js} +42 -42
- package/dist/cli/chunks/{chunk-MTBGOWJA.js → chunk-X2K3BTI4.js} +2 -2
- package/dist/cli/chunks/{chunk-NCSXLMDL.js → chunk-XDRAU3W6.js} +2 -2
- package/dist/cli/chunks/{chunk-URP75DL4.js → chunk-XJTGLG7G.js} +1 -1
- package/dist/cli/chunks/{chunk-TRNBQFFG.js → chunk-XS6BIOPQ.js} +2 -2
- package/dist/cli/chunks/{chunk-MEIU7457.js → chunk-XTAXSKPC.js} +2 -2
- package/dist/cli/chunks/{chunk-VN2HHBZN.js → chunk-XYV6YUWS.js} +2 -2
- package/dist/cli/chunks/{chunk-UORTQXJ2.js → chunk-YGB3MT3R.js} +1 -1
- package/dist/cli/chunks/{chunk-37ZUF5NX.js → chunk-YNXQMJGJ.js} +1 -1
- package/dist/cli/chunks/{chunk-BLPWJQTY.js → chunk-ZCDGLNJ7.js} +2 -2
- package/dist/cli/chunks/{chunk-62UM7Q5N.js → chunk-ZNITDSWL.js} +1 -1
- package/dist/cli/chunks/{ci-CBNVLOOQ.js → ci-IU5HVUL5.js} +2 -2
- package/dist/cli/chunks/{ci-output-I4HY2FYJ.js → ci-output-CLI4A43F.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-5VRBKGWL.js → circuit-breaker-ZR5OFMW7.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-XPJPKHIO.js → claude-flow-setup-UBMA6ZHJ.js} +2 -2
- package/dist/cli/chunks/client-KKCFGD7R.js +2 -0
- package/dist/cli/chunks/{cline-installer-OFRDUUWZ.js → cline-installer-EWYELOBI.js} +2 -2
- package/dist/cli/chunks/{code-QIZQVB3E.js → code-YSPF4MXN.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-LMUUWEX4.js → code-index-extractor-WW5OKSTN.js} +2 -2
- package/dist/cli/chunks/{codex-installer-N2MKIZ2S.js → codex-installer-GLADK5PY.js} +2 -2
- package/dist/cli/chunks/{completions-Y36S3C5J.js → completions-2KTWZ3AK.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-73YS3WUD.js → complexity-analyzer-KMX4OWKB.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-SAOTP6J3.js → continuedev-installer-4FHU4OEJ.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-A4HXF6HE.js → copilot-installer-AKR4WE7B.js} +2 -2
- package/dist/cli/chunks/core-handlers-KRSSJEO5.js +2 -0
- package/dist/cli/chunks/{cost-tracker-P26XUVZS.js → cost-tracker-BUJ6WEWY.js} +2 -2
- package/dist/cli/chunks/{coverage-HVNHSMVJ.js → coverage-OB6HVQS4.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-27QGWU27.js +2 -0
- package/dist/cli/chunks/{cursor-installer-46BQFTYZ.js → cursor-installer-3AOE4O3Q.js} +2 -2
- package/dist/cli/chunks/{daemon-Y54O3FLT.js → daemon-4RAL5URG.js} +3 -3
- package/dist/cli/chunks/{daemon-YE7K2AZF.js → daemon-JGSPLYGO.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-ETA7YY52.js → dag-attention-scheduler-DSBTHIMH.js} +2 -2
- package/dist/cli/chunks/{detect-5WLQ2J3E.js → detect-6CVW2VUQ.js} +2 -2
- package/dist/cli/chunks/{dist-node-45WW6I7J.js → dist-node-EWPKBTYA.js} +2 -2
- package/dist/cli/chunks/{domain-handler-J7DQV74M.js → domain-handler-HLVIJU25.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-GD2EGQVR.js → domain-transfer-7Y3BR3YU.js} +2 -2
- package/dist/cli/chunks/dream-M6K47Q4H.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-JELNEA2D.js → embed-and-insert-pattern-ZMJ3263X.js} +2 -2
- package/dist/cli/chunks/{eval-A4PA5G2U.js → eval-73XW2WJD.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-MLHTYWTA.js → experience-capture-middleware-OGJ3JOSQ.js} +3 -3
- package/dist/cli/chunks/{fast-paths-QYDTITRV.js → fast-paths-5XCY3Y6U.js} +2 -2
- package/dist/cli/chunks/{feature-flags-H4MSY26Z.js → feature-flags-R5V2FRJR.js} +2 -2
- package/dist/cli/chunks/{feature-flags-MQYYRHIK.js → feature-flags-VULQI6KY.js} +2 -2
- package/dist/cli/chunks/{file-discovery-RMFVJNGL.js → file-discovery-HW33C3HC.js} +2 -2
- package/dist/cli/chunks/{fleet-7KZQOTAC.js → fleet-NH3XR5OY.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-NMZFTGVH.js → gnn-wrapper-L3XMLPTG.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-7BQDK7MG.js → heartbeat-handler-TIQFBT4D.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-URXBF5RW.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-WWAGM6HK.js +2 -0
- package/dist/cli/chunks/hnsw-index-UFV2HSZE.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-TPPGBPKF.js → hnsw-legacy-bridge-YL2SUIPA.js} +2 -2
- package/dist/cli/chunks/{better-sqlite3-2KR4LQRU.js → hnswlib-node-62RTSHAY.js} +2 -2
- package/dist/cli/chunks/{hooks-CYZIUYSH.js → hooks-UR2ZF54G.js} +10 -10
- package/dist/cli/chunks/hybrid-router-3U6Q6OTL.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-WC6DMTYQ.js → hypergraph-engine-NX45AOPY.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-GTGA3TXJ.js → hypergraph-handler-LUM4YI4K.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-EUEX6ZRO.js +2 -0
- package/dist/cli/chunks/{init-handler-N3Z72JNI.js → init-handler-YTKKNTVV.js} +6 -6
- package/dist/cli/chunks/init-wizard-POKY2LRY.js +2 -0
- package/dist/cli/chunks/kernel-HPAONLZY.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-FUX4V6II.js → kilocode-installer-ZW7DVH7T.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-ZSNZT7ZR.js → kiro-installer-IA7INW4N.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-2WCUFG63.js +2 -0
- package/dist/cli/chunks/{learning-UQY64COU.js → learning-4AZ5PGTT.js} +3 -3
- package/dist/cli/chunks/{llm-router-CMHGGX6N.js → llm-router-WQ4E3AOP.js} +4 -4
- package/dist/cli/chunks/llm-router-service-D5VMG6SD.js +2 -0
- package/dist/cli/chunks/{load-E6WH4QN2.js → load-4FAH7CZO.js} +2 -2
- package/dist/cli/chunks/load-test-DHG26REU.js +2 -0
- package/dist/cli/chunks/{mcp-UM5VTW6N.js → mcp-KLLHI6DG.js} +2 -2
- package/dist/cli/chunks/{memory-7Q3XDUE5.js → memory-Q5HLIUC6.js} +5 -5
- package/dist/cli/chunks/memory-backend-GLWQ4DAL.js +2 -0
- package/dist/cli/chunks/memory-handlers-P72I4VV4.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-LZENWVRR.js → multi-model-executor-ABI73AFV.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-O2JAIPLF.js → opencode-installer-KRPQ6JOJ.js} +2 -2
- package/dist/cli/chunks/{orchestrator-DKZWXDRI.js → orchestrator-SUPEONRG.js} +18 -18
- package/dist/cli/chunks/pattern-null-store-Y2YFTE3V.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-CLUL4M55.js → pattern-usage-recorder-R4GKK6RZ.js} +2 -2
- package/dist/cli/chunks/{pipeline-2VDLTR5J.js → pipeline-LCUETNGD.js} +2 -2
- package/dist/cli/chunks/{platform-4N4Q5XYX.js → platform-WJDIB4X3.js} +2 -2
- package/dist/cli/chunks/{plugin-GY5AU5CS.js → plugin-2X5NY2RF.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-TQ4DKDZS.js → prime-radiant-advanced-wasm-3T665QC6.js} +2 -2
- package/dist/cli/chunks/protocol-executor-HNT67NN5.js +2 -0
- package/dist/cli/chunks/{protocol-handler-T3LZ3WRG.js → protocol-handler-JTXRF7GU.js} +2 -2
- package/dist/cli/chunks/{prove-OV7S5J4W.js → prove-BFPWWPOC.js} +2 -2
- package/dist/cli/chunks/provider-manager-5YGPZIEZ.js +2 -0
- package/dist/cli/chunks/qe-reasoning-bank-Z5UGOA3F.js +2 -0
- package/dist/cli/chunks/{quality-AXD4NLQA.js → quality-F7UZU4RN.js} +2 -2
- package/dist/cli/chunks/quality-gate-R5L4UZIX.js +7 -0
- package/dist/cli/chunks/queen-coordinator-P5LU5NWI.js +2 -0
- package/dist/cli/chunks/{real-embeddings-2PUCC7FG.js → real-embeddings-LZD6HTQF.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-WJ5ARGLW.js → roocode-installer-6TTG7VSH.js} +2 -2
- package/dist/cli/chunks/router-CRGHUAVR.js +2 -0
- package/dist/cli/chunks/routing-feedback-BVX5ZBCF.js +2 -0
- package/dist/cli/chunks/{routing-handler-CU6657SZ.js → routing-handler-SW442GK7.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-IIF6VSFW.js → ruvector-commands-CLFGKXMW.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-YMQI7XO2.js → rvf-dual-writer-EVPPXXXS.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-HDE3PR2W.js → rvf-migration-adapter-NOHDIRIP.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-MQV5OA7K.js → rvf-migration-coordinator-BYJ3M7WZ.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-FZJSQOJM.js +2 -0
- package/dist/cli/chunks/safe-db-USYNEOC6.js +2 -0
- package/dist/cli/chunks/schedule-KCRCQ3PS.js +2 -0
- package/dist/cli/chunks/scheduler-CX3UHI4U.js +2 -0
- package/dist/cli/chunks/{security-UM3IGDSM.js → security-IXDKBPSG.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-I3SOJ6M4.js → shared-rvf-adapter-VCOK3OVD.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-KQGC2UO7.js → shared-rvf-dual-writer-FFKBKYNL.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-K23C4TFH.js +2 -0
- package/dist/cli/chunks/{status-handler-OX4CJZME.js → status-handler-M5W64S5U.js} +2 -2
- package/dist/cli/chunks/{structural-health-PYUMVBXJ.js → structural-health-55X6BTLT.js} +2 -2
- package/dist/cli/chunks/{sync-VALFNTA6.js → sync-BUGDXW3Y.js} +2 -2
- package/dist/cli/chunks/{sync-2TED3YTY.js → sync-NUG67HGK.js} +2 -2
- package/dist/cli/chunks/{task-handler-VPGAJVPC.js → task-handler-T6ZKXV4S.js} +2 -2
- package/dist/cli/chunks/{task-handlers-IB4UAMU6.js → task-handlers-H63TB2UI.js} +3 -3
- package/dist/cli/chunks/{test-OMRJOZB6.js → test-VEK76SBT.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-ZL3YFPBU.js → test-scheduling-QZM6PNZH.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-DNWZI7SH.js → token-bootstrap-W5IAMJW4.js} +2 -2
- package/dist/cli/chunks/{token-usage-IYO7RGFF.js → token-usage-OBY6UEUR.js} +2 -2
- package/dist/cli/chunks/{transformers-53ALC34T.js → transformers-EFNY2MRX.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-WUKJ2I2Q.js → tree-sitter-wasm-parser-EU2S5NVM.js} +2 -2
- package/dist/cli/chunks/{types-47FTEPMV.js → types-3DYRKX23.js} +2 -2
- package/dist/cli/chunks/unified-memory-NCDBQLLF.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-T7NSGQ2H.js +2 -0
- package/dist/cli/chunks/unified-persistence-XUAYDCMM.js +2 -0
- package/dist/cli/chunks/{upgrade-QPLMJA5Z.js → upgrade-H5V53FRF.js} +2 -2
- package/dist/cli/chunks/{validate-3GVKZOVF.js → validate-IL22VB5I.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-XCRTLVM6.js → validate-swarm-WZKECK3W.js} +2 -2
- package/dist/cli/chunks/{vibium-CH4VPKVZ.js → vibium-KKM23OTQ.js} +2 -2
- package/dist/cli/chunks/visual-security-3TUC4GPP.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-JDBNAZTV.js → web-tree-sitter-NJM5YBOY.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-3MNPVJBP.js → windsurf-installer-SLP43TVT.js} +2 -2
- package/dist/cli/chunks/witness-chain-QLOKUZXC.js +2 -0
- package/dist/cli/chunks/{witness-chain-HR5UBV5J.js → witness-chain-XBEPT4XD.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-G5SQTIBZ.js → witness-key-manager-DAAMNYOW.js} +2 -2
- package/dist/cli/chunks/{workflow-43EMD5FY.js → workflow-SZOOU6D3.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-6JAYTZ7L.js +2 -0
- package/dist/cli/chunks/{wrappers-3N7AYNM3.js → wrappers-I2CBKWGF.js} +2 -2
- package/dist/cli/commands/quality-gate.d.ts +24 -0
- package/dist/cli/commands/quality-gate.js +135 -0
- package/dist/cli/index.js +5 -0
- package/dist/coordination/mincut/dream-integration.d.ts +11 -0
- package/dist/coordination/mincut/dream-integration.js +39 -12
- package/dist/init/init-wizard-hooks.js +11 -25
- package/dist/init/phases/07-hooks.js +15 -25
- package/dist/init/settings-merge.d.ts +44 -0
- package/dist/init/settings-merge.js +119 -4
- package/dist/integrations/ruvector/feature-flags.js +7 -0
- package/dist/learning/pattern-lifecycle.d.ts +16 -0
- package/dist/learning/pattern-lifecycle.js +77 -1
- package/dist/learning/provenance-tier.d.ts +52 -0
- package/dist/learning/provenance-tier.js +64 -0
- package/dist/learning/qe-flywheel/corpus-scorer.d.ts +55 -0
- package/dist/learning/qe-flywheel/corpus-scorer.js +293 -0
- package/dist/learning/qe-flywheel/coupled-anchor.d.ts +91 -0
- package/dist/learning/qe-flywheel/coupled-anchor.js +181 -0
- package/dist/learning/qe-flywheel/generation.d.ts +121 -0
- package/dist/learning/qe-flywheel/generation.js +167 -0
- package/dist/learning/qe-flywheel/policy.d.ts +37 -0
- package/dist/learning/qe-flywheel/policy.js +66 -0
- package/dist/learning/qe-flywheel/receipt-store.d.ts +31 -0
- package/dist/learning/qe-flywheel/receipt-store.js +89 -0
- package/dist/learning/qe-flywheel/receipt.d.ts +62 -0
- package/dist/learning/qe-flywheel/receipt.js +97 -0
- package/dist/mcp/bundle.js +396 -390
- package/dist/mcp/tools/quality-assessment/gate.d.ts +38 -0
- package/dist/mcp/tools/quality-assessment/gate.js +86 -0
- package/dist/mcp/tools/registry.d.ts +1 -0
- package/dist/mcp/tools/registry.js +3 -0
- package/dist/shared/safe-db.js +23 -4
- package/dist/validation/anchor-set.d.ts +74 -0
- package/dist/validation/anchor-set.js +78 -0
- package/dist/validation/frontier-judge.d.ts +99 -0
- package/dist/validation/frontier-judge.js +234 -0
- package/dist/validation/gate-reexecute.d.ts +165 -0
- package/dist/validation/gate-reexecute.js +255 -0
- package/dist/validation/quality-gate-runner.d.ts +49 -0
- package/dist/validation/quality-gate-runner.js +62 -0
- package/dist/validation/quality-verdict.d.ts +94 -0
- package/dist/validation/quality-verdict.js +120 -0
- package/package.json +1 -1
- package/dist/cli/chunks/adapter-KNM5R47J.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-MXPJLVR3.js +0 -2
- package/dist/cli/chunks/base-X4EXQ2AS.js +0 -2
- package/dist/cli/chunks/browser-workflow-4HX6RP5F.js +0 -2
- package/dist/cli/chunks/chunk-FHTYEAQ3.js +0 -2
- package/dist/cli/chunks/chunk-MIU5RUBJ.js +0 -149
- package/dist/cli/chunks/chunk-SK754ZSH.js +0 -316
- package/dist/cli/chunks/chunk-V6NAB5UZ.js +0 -2
- package/dist/cli/chunks/chunk-YR2JKBZO.js +0 -2
- package/dist/cli/chunks/chunk-ZMPAM4DY.js +0 -2
- package/dist/cli/chunks/client-AHXNCOHK.js +0 -2
- package/dist/cli/chunks/core-handlers-EEFLLMAZ.js +0 -2
- package/dist/cli/chunks/cross-domain-router-LT3H4SNJ.js +0 -2
- package/dist/cli/chunks/dream-4K3BK4IG.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-IMPPGQUK.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-EIAA6R2L.js +0 -2
- package/dist/cli/chunks/hnsw-index-ZXXP6AXZ.js +0 -2
- package/dist/cli/chunks/hybrid-router-LXWG4MLH.js +0 -2
- package/dist/cli/chunks/impact-analyzer-TP5LRFYH.js +0 -2
- package/dist/cli/chunks/init-wizard-AIOA5KOY.js +0 -2
- package/dist/cli/chunks/kernel-SQALRU6Q.js +0 -2
- package/dist/cli/chunks/knowledge-graph-JFVT6SNN.js +0 -2
- package/dist/cli/chunks/llm-router-service-XHFKTH3I.js +0 -2
- package/dist/cli/chunks/load-test-JEIFJKNN.js +0 -2
- package/dist/cli/chunks/memory-backend-NT7I37CP.js +0 -2
- package/dist/cli/chunks/memory-handlers-746D7NE7.js +0 -2
- package/dist/cli/chunks/pattern-null-store-6QU6WHDW.js +0 -2
- package/dist/cli/chunks/protocol-executor-GT2MZYUU.js +0 -2
- package/dist/cli/chunks/provider-manager-OATJ7R3D.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-IJXNQ67O.js +0 -2
- package/dist/cli/chunks/queen-coordinator-6RBHWCUG.js +0 -2
- package/dist/cli/chunks/router-XKQRT5JK.js +0 -2
- package/dist/cli/chunks/routing-feedback-ACPSD4LW.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-SIWRKE33.js +0 -2
- package/dist/cli/chunks/safe-db-LCPUYMX4.js +0 -2
- package/dist/cli/chunks/schedule-HIQJCWXG.js +0 -2
- package/dist/cli/chunks/scheduler-QE5EJ5LE.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-EU54UTMH.js +0 -2
- package/dist/cli/chunks/unified-memory-CJLMC2I4.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-FDGR4D2J.js +0 -2
- package/dist/cli/chunks/unified-persistence-UFH5GLDN.js +0 -2
- package/dist/cli/chunks/visual-security-4ARJ7J2Y.js +0 -2
- package/dist/cli/chunks/witness-chain-73QC33ED.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-RKMMPXNA.js +0 -2
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { v4 as uuidv4 } from 'uuid';
|
|
23
23
|
import { StrangeLoopController } from './strange-loop';
|
|
24
|
+
import { DEFAULT_PROVENANCE_TIER } from '../../learning/provenance-tier.js';
|
|
25
|
+
import { reExecutePathGate, pathGateFingerprint, pathSealedHash, verifyPathPromotion, } from '../../validation/gate-reexecute.js';
|
|
24
26
|
/**
|
|
25
27
|
* Default dream integration configuration
|
|
26
28
|
*/
|
|
@@ -930,19 +932,44 @@ export class DreamMinCutController {
|
|
|
930
932
|
continue;
|
|
931
933
|
}
|
|
932
934
|
const action = this.integration.convertInsightToAction(insight);
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
935
|
+
const actionable = !!action && action.type !== 'no_action';
|
|
936
|
+
// ADR-120: seal the apply decision's inputs and re-execute the frozen
|
|
937
|
+
// `dream-apply/v1` rule. This is the A8-EXT fake-`applied`-counter home:
|
|
938
|
+
// a logged apply the frozen rule would reject (proxy-tier evidence, or an
|
|
939
|
+
// insight that produced no real reorganization) is a forgery. Only a
|
|
940
|
+
// receipt that re-executes to `promote` on intact sealed inputs is
|
|
941
|
+
// counted as applied — the log no longer decides, the re-run does.
|
|
942
|
+
const sealed = {
|
|
943
|
+
provenanceTier: insight.provenanceTier ?? DEFAULT_PROVENANCE_TIER,
|
|
944
|
+
allowJudgeTier: this.config.allowJudgeTierApply,
|
|
945
|
+
insightConfidence: insight.confidenceScore,
|
|
946
|
+
insightConfidenceThreshold: this.config.insightConfidenceThreshold,
|
|
947
|
+
insightActionable: actionable,
|
|
948
|
+
};
|
|
949
|
+
const rerun = reExecutePathGate('dream-apply/v1', sealed);
|
|
950
|
+
const receipt = {
|
|
951
|
+
ruleVersion: 'dream-apply/v1',
|
|
952
|
+
ruleFingerprint: pathGateFingerprint('dream-apply/v1'),
|
|
953
|
+
sealedHash: pathSealedHash(sealed),
|
|
954
|
+
sealed,
|
|
955
|
+
recordedVerdict: rerun.promote ? 'promote' : 'reject',
|
|
956
|
+
};
|
|
957
|
+
const verdict = verifyPathPromotion(receipt);
|
|
958
|
+
if (!verdict.valid || !rerun.promote) {
|
|
959
|
+
continue; // not reproducibly applicable under the frozen rule — do not count
|
|
945
960
|
}
|
|
961
|
+
// Record as adaptation
|
|
962
|
+
this.integration.getMetaTracker().recordAdaptation({
|
|
963
|
+
timestamp: new Date(),
|
|
964
|
+
type: 'insight_applied',
|
|
965
|
+
trigger: 'dream_insight',
|
|
966
|
+
stateBefore: { minCutValue: 0, weakVertexCount: 0 },
|
|
967
|
+
stateAfter: { minCutValue: 0, weakVertexCount: 0 },
|
|
968
|
+
improvement: insight.noveltyScore * insight.confidenceScore,
|
|
969
|
+
insightId: insight.id,
|
|
970
|
+
});
|
|
971
|
+
insight.applied = true;
|
|
972
|
+
appliedCount++;
|
|
946
973
|
}
|
|
947
974
|
return appliedCount;
|
|
948
975
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { existsSync, mkdirSync, writeFileSync, readFileSync, copyFileSync } from 'fs';
|
|
13
13
|
import { join, dirname } from 'path';
|
|
14
14
|
import { safeJsonParse } from '../shared/safe-json.js';
|
|
15
|
-
import { mergeHooksSmart, generateAqeEnvVars, generateV3SettingsSections, } from './settings-merge.js';
|
|
15
|
+
import { mergeHooksSmart, generateAqeEnvVars, generateV3SettingsSections, applyV3Sections, mergeAqeEnv, backupSettingsFile, } from './settings-merge.js';
|
|
16
16
|
// ============================================================================
|
|
17
17
|
// Hook Configuration
|
|
18
18
|
// ============================================================================
|
|
@@ -183,31 +183,15 @@ export async function configureHooks(projectRoot, config) {
|
|
|
183
183
|
// Smart merge: replace old AQE hooks, keep user hooks, add new AQE hooks
|
|
184
184
|
const existingHooks = settings.hooks || {};
|
|
185
185
|
settings.hooks = mergeHooksSmart(existingHooks, aqeHooks);
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
settings.env
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
//
|
|
193
|
-
// Permissions are union-merged to preserve user entries (#362)
|
|
186
|
+
// Add AQE environment variables without clobbering any value the user already
|
|
187
|
+
// set — including AQE_-prefixed overrides (only missing keys are added).
|
|
188
|
+
const existingEnv = settings.env;
|
|
189
|
+
settings.env = mergeAqeEnv(existingEnv, generateAqeEnvVars(config));
|
|
190
|
+
// Apply v3 settings sections non-destructively: permissions union-merged,
|
|
191
|
+
// statusLine / includeCoAuthoredBy preserved when user-set, AQE-owned
|
|
192
|
+
// sections deep-merged so user additions survive (#362 follow-up).
|
|
194
193
|
const v3Sections = generateV3SettingsSections(config, projectRoot);
|
|
195
|
-
|
|
196
|
-
if (key === '_aqePermissions') {
|
|
197
|
-
// Union-merge: add AQE entries without removing user-added permissions
|
|
198
|
-
const existingPerms = settings.permissions || {};
|
|
199
|
-
const existingAllow = existingPerms.allow || [];
|
|
200
|
-
const aqeEntries = value;
|
|
201
|
-
const merged = [...new Set([...existingAllow, ...aqeEntries])];
|
|
202
|
-
settings.permissions = {
|
|
203
|
-
...existingPerms,
|
|
204
|
-
allow: merged,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
settings[key] = value;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
194
|
+
applyV3Sections(settings, v3Sections);
|
|
211
195
|
// Enable MCP servers (deduplicate, replace old 'aqe' with 'agentic-qe')
|
|
212
196
|
let existingMcp = settings.enabledMcpjsonServers || [];
|
|
213
197
|
existingMcp = existingMcp.filter(s => s !== 'aqe');
|
|
@@ -215,6 +199,8 @@ export async function configureHooks(projectRoot, config) {
|
|
|
215
199
|
existingMcp.push('agentic-qe');
|
|
216
200
|
}
|
|
217
201
|
settings.enabledMcpjsonServers = existingMcp;
|
|
202
|
+
// Back up the pristine original settings.json before writing (like CLAUDE.md)
|
|
203
|
+
backupSettingsFile(settingsPath);
|
|
218
204
|
writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
|
|
219
205
|
// Install cross-phase memory hooks configuration
|
|
220
206
|
await installCrossPhaseMemoryHooks(projectRoot);
|
|
@@ -13,7 +13,7 @@ import { fileURLToPath } from 'url';
|
|
|
13
13
|
import { safeJsonParse } from '../../shared/safe-json.js';
|
|
14
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname = dirname(__filename);
|
|
16
|
-
import { isAqeHookEntry, mergeHooksSmart, generateAqeEnvVars, generateV3SettingsSections, } from '../settings-merge.js';
|
|
16
|
+
import { isAqeHookEntry, mergeHooksSmart, generateAqeEnvVars, generateV3SettingsSections, applyV3Sections, mergeAqeEnv, backupSettingsFile, } from '../settings-merge.js';
|
|
17
17
|
import { BasePhase, } from './phase-interface.js';
|
|
18
18
|
/**
|
|
19
19
|
* Hooks phase - configures Claude Code hooks
|
|
@@ -76,31 +76,16 @@ export class HooksPhase extends BasePhase {
|
|
|
76
76
|
}
|
|
77
77
|
// Smart merge: remove old AQE hooks, keep user hooks, add new AQE hooks
|
|
78
78
|
settings.hooks = mergeHooksSmart(existingHooks, aqeHooks);
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
settings.env
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
//
|
|
86
|
-
//
|
|
79
|
+
// Add AQE environment variables without clobbering any value the user
|
|
80
|
+
// already set — including AQE_-prefixed overrides (only missing keys added).
|
|
81
|
+
const existingEnv = settings.env;
|
|
82
|
+
settings.env = mergeAqeEnv(existingEnv, generateAqeEnvVars(config));
|
|
83
|
+
// Apply v3 settings sections non-destructively:
|
|
84
|
+
// - permissions union-merged (preserve user entries, #362)
|
|
85
|
+
// - statusLine / includeCoAuthoredBy preserved when user-set (#362 follow-up)
|
|
86
|
+
// - AQE-owned sections deep-merged so user additions survive
|
|
87
87
|
const v3Sections = generateV3SettingsSections(config, projectRoot);
|
|
88
|
-
|
|
89
|
-
if (key === '_aqePermissions') {
|
|
90
|
-
// Union-merge: add AQE entries without removing user-added permissions
|
|
91
|
-
const existingPerms = settings.permissions || {};
|
|
92
|
-
const existingAllow = existingPerms.allow || [];
|
|
93
|
-
const aqeEntries = value;
|
|
94
|
-
const merged = [...new Set([...existingAllow, ...aqeEntries])];
|
|
95
|
-
settings.permissions = {
|
|
96
|
-
...existingPerms,
|
|
97
|
-
allow: merged,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
settings[key] = value;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
88
|
+
applyV3Sections(settings, v3Sections);
|
|
104
89
|
// Enable MCP servers (deduplicate, replace old 'aqe' with 'agentic-qe')
|
|
105
90
|
let existingMcp = settings.enabledMcpjsonServers || [];
|
|
106
91
|
// Remove legacy 'aqe' entry if present (renamed to 'agentic-qe')
|
|
@@ -109,6 +94,11 @@ export class HooksPhase extends BasePhase {
|
|
|
109
94
|
existingMcp.push('agentic-qe');
|
|
110
95
|
}
|
|
111
96
|
settings.enabledMcpjsonServers = existingMcp;
|
|
97
|
+
// Back up the pristine original settings.json before writing (like CLAUDE.md)
|
|
98
|
+
const backupPath = backupSettingsFile(settingsPath);
|
|
99
|
+
if (backupPath) {
|
|
100
|
+
context.services.log(` Backup created: ${backupPath}`);
|
|
101
|
+
}
|
|
112
102
|
// Write settings
|
|
113
103
|
writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
|
|
114
104
|
// Write README and install hook assets (bridge script, cross-phase memory)
|
|
@@ -8,6 +8,18 @@
|
|
|
8
8
|
* - Generates full env vars and v3 settings sections
|
|
9
9
|
*/
|
|
10
10
|
import type { AQEInitConfig } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Create a one-time `.backup` of an existing settings.json before AQE modifies
|
|
13
|
+
* it — mirroring the CLAUDE.md backup convention.
|
|
14
|
+
*
|
|
15
|
+
* The backup captures the pristine, pre-AQE file and is NOT overwritten on
|
|
16
|
+
* subsequent re-inits, so the user's original settings are always recoverable.
|
|
17
|
+
* No-op when the file does not exist yet (fresh install) or a backup already
|
|
18
|
+
* exists. Failures are swallowed — a backup problem must never block init.
|
|
19
|
+
*
|
|
20
|
+
* @returns the backup path when a backup was written, otherwise null.
|
|
21
|
+
*/
|
|
22
|
+
export declare function backupSettingsFile(settingsPath: string): string | null;
|
|
11
23
|
/**
|
|
12
24
|
* Check if a single hook entry belongs to AQE (any variant).
|
|
13
25
|
* Matches commands containing 'aqe' or 'agentic-qe' in any form.
|
|
@@ -23,10 +35,42 @@ export declare function isAqeHookEntry(entry: unknown): boolean;
|
|
|
23
35
|
* 3. Preserve any hook types not in the new config
|
|
24
36
|
*/
|
|
25
37
|
export declare function mergeHooksSmart(existingHooks: Record<string, unknown[]>, newAqeHooks: Record<string, unknown[]>): Record<string, unknown[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Merge AQE's environment variables into a user's existing `env` block WITHOUT
|
|
40
|
+
* clobbering values the user already set — including AQE_-prefixed ones.
|
|
41
|
+
*
|
|
42
|
+
* Re-running `aqe init` fills in any missing AQE env vars but leaves every
|
|
43
|
+
* existing value untouched, so a user who intentionally flipped, say,
|
|
44
|
+
* `AQE_LEARNING_ENABLED=false` keeps their choice. Non-AQE env vars are always
|
|
45
|
+
* preserved. Returns a new object; inputs are not mutated.
|
|
46
|
+
*/
|
|
47
|
+
export declare function mergeAqeEnv(existingEnv: Record<string, string> | undefined, aqeEnv: Record<string, string>): Record<string, string>;
|
|
26
48
|
/**
|
|
27
49
|
* Generate the full set of AQE environment variables for settings.json.
|
|
28
50
|
*/
|
|
29
51
|
export declare function generateAqeEnvVars(config: AQEInitConfig): Record<string, string>;
|
|
52
|
+
/**
|
|
53
|
+
* Detect whether a `statusLine` block is one AQE generated (vs. a user's own).
|
|
54
|
+
* AQE's status line invokes the statusline-v3.cjs helper (or falls back to the
|
|
55
|
+
* "Agentic QE v3" banner). Anything else is treated as user-owned and preserved.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isAqeStatusLine(statusLine: unknown): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Apply the generated v3 settings sections onto an existing settings object
|
|
60
|
+
* WITHOUT clobbering configuration the user already set:
|
|
61
|
+
*
|
|
62
|
+
* - `_aqePermissions`: union-merge into `permissions.allow`, preserving the
|
|
63
|
+
* user's existing allow/deny entries (#362).
|
|
64
|
+
* - `statusLine`: generic Claude Code setting — only written when absent or when
|
|
65
|
+
* the existing one is AQE's own (so a user's custom status line is preserved).
|
|
66
|
+
* - `includeCoAuthoredBy`: generic Claude Code setting — only written when the
|
|
67
|
+
* user has not set it explicitly (respects an intentional `false`).
|
|
68
|
+
* - `aqe` / `v3Configuration` / `v3Learning`: AQE-owned sections, deep-merged so
|
|
69
|
+
* AQE values are refreshed while any user-added keys survive.
|
|
70
|
+
*
|
|
71
|
+
* Mutates and returns `settings`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function applyV3Sections(settings: Record<string, unknown>, sections: Record<string, unknown>): Record<string, unknown>;
|
|
30
74
|
/**
|
|
31
75
|
* Generate v3-specific settings sections for settings.json.
|
|
32
76
|
* These sections enable the self-learning system, status line, and permissions.
|
|
@@ -7,16 +7,49 @@
|
|
|
7
7
|
* - Preserves non-AQE hooks from the user's config
|
|
8
8
|
* - Generates full env vars and v3 settings sections
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
11
|
+
/**
|
|
12
|
+
* Create a one-time `.backup` of an existing settings.json before AQE modifies
|
|
13
|
+
* it — mirroring the CLAUDE.md backup convention.
|
|
14
|
+
*
|
|
15
|
+
* The backup captures the pristine, pre-AQE file and is NOT overwritten on
|
|
16
|
+
* subsequent re-inits, so the user's original settings are always recoverable.
|
|
17
|
+
* No-op when the file does not exist yet (fresh install) or a backup already
|
|
18
|
+
* exists. Failures are swallowed — a backup problem must never block init.
|
|
19
|
+
*
|
|
20
|
+
* @returns the backup path when a backup was written, otherwise null.
|
|
21
|
+
*/
|
|
22
|
+
export function backupSettingsFile(settingsPath) {
|
|
23
|
+
if (!existsSync(settingsPath))
|
|
24
|
+
return null;
|
|
25
|
+
const backupPath = `${settingsPath}.backup`;
|
|
26
|
+
if (existsSync(backupPath))
|
|
27
|
+
return null; // keep the pristine original
|
|
28
|
+
try {
|
|
29
|
+
writeFileSync(backupPath, readFileSync(settingsPath, 'utf-8'), 'utf-8');
|
|
30
|
+
return backupPath;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Patterns that identify a hook command as belonging to AQE.
|
|
37
|
+
//
|
|
38
|
+
// These MUST be specific to AQE's own hooks. They must NOT match hooks that
|
|
39
|
+
// other tools install (e.g. ruflo / claude-flow), otherwise re-running
|
|
40
|
+
// `aqe init` in a project that already ran `ruflo init` would strip the user's
|
|
41
|
+
// ruflo hooks. In particular:
|
|
42
|
+
// - do NOT match on `.claude/helpers/` broadly — ruflo's hook-handler.cjs and
|
|
43
|
+
// auto-memory-hook.mjs live there too (match AQE's own helpers by name)
|
|
44
|
+
// - do NOT match on `ruflo` — those are the user's hooks, preserve them
|
|
11
45
|
const AQE_COMMAND_PATTERNS = [
|
|
12
46
|
/\baqe\b/i,
|
|
13
47
|
/\bagentic-qe\b/i,
|
|
14
48
|
/\bnpx\s+agentic-qe\b/i,
|
|
15
49
|
/\bnpx\s+@anthropics\/agentic-qe\b/i,
|
|
50
|
+
/aqe-hook\.cjs/i,
|
|
16
51
|
/brain-checkpoint\.cjs/i,
|
|
17
|
-
|
|
18
|
-
/\bruflo\b/i,
|
|
19
|
-
/dist\/cli\/bundle\.js/i,
|
|
52
|
+
/statusline-v3\.cjs/i,
|
|
20
53
|
];
|
|
21
54
|
/**
|
|
22
55
|
* Check if a single hook entry belongs to AQE (any variant).
|
|
@@ -62,6 +95,19 @@ export function mergeHooksSmart(existingHooks, newAqeHooks) {
|
|
|
62
95
|
}
|
|
63
96
|
return merged;
|
|
64
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Merge AQE's environment variables into a user's existing `env` block WITHOUT
|
|
100
|
+
* clobbering values the user already set — including AQE_-prefixed ones.
|
|
101
|
+
*
|
|
102
|
+
* Re-running `aqe init` fills in any missing AQE env vars but leaves every
|
|
103
|
+
* existing value untouched, so a user who intentionally flipped, say,
|
|
104
|
+
* `AQE_LEARNING_ENABLED=false` keeps their choice. Non-AQE env vars are always
|
|
105
|
+
* preserved. Returns a new object; inputs are not mutated.
|
|
106
|
+
*/
|
|
107
|
+
export function mergeAqeEnv(existingEnv, aqeEnv) {
|
|
108
|
+
// AQE defaults first, then existing values win on any key collision.
|
|
109
|
+
return { ...aqeEnv, ...(existingEnv || {}) };
|
|
110
|
+
}
|
|
65
111
|
/**
|
|
66
112
|
* Generate the full set of AQE environment variables for settings.json.
|
|
67
113
|
*/
|
|
@@ -85,6 +131,75 @@ export function generateAqeEnvVars(config) {
|
|
|
85
131
|
AQE_V3_SUCCESS_RATE_THRESHOLD: String(config.learning?.qualityThreshold ?? 0.7),
|
|
86
132
|
};
|
|
87
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Detect whether a `statusLine` block is one AQE generated (vs. a user's own).
|
|
136
|
+
* AQE's status line invokes the statusline-v3.cjs helper (or falls back to the
|
|
137
|
+
* "Agentic QE v3" banner). Anything else is treated as user-owned and preserved.
|
|
138
|
+
*/
|
|
139
|
+
export function isAqeStatusLine(statusLine) {
|
|
140
|
+
const cmd = statusLine?.command;
|
|
141
|
+
return typeof cmd === 'string' && /statusline-v3\.cjs|Agentic QE v3/.test(cmd);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Deep-merge `source` (AQE-owned values) onto `target` (whatever the user has):
|
|
145
|
+
* plain-object subtrees merge recursively so a user's extra keys survive, while
|
|
146
|
+
* AQE's values win on conflicting leaves. Arrays and primitives are replaced by
|
|
147
|
+
* the AQE value (these sections are AQE-managed).
|
|
148
|
+
*/
|
|
149
|
+
function deepMergeOwned(target, source) {
|
|
150
|
+
if (!isPlainObject(target) || !isPlainObject(source))
|
|
151
|
+
return source;
|
|
152
|
+
const out = { ...target };
|
|
153
|
+
for (const [key, value] of Object.entries(source)) {
|
|
154
|
+
out[key] = deepMergeOwned(out[key], value);
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
function isPlainObject(value) {
|
|
159
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Apply the generated v3 settings sections onto an existing settings object
|
|
163
|
+
* WITHOUT clobbering configuration the user already set:
|
|
164
|
+
*
|
|
165
|
+
* - `_aqePermissions`: union-merge into `permissions.allow`, preserving the
|
|
166
|
+
* user's existing allow/deny entries (#362).
|
|
167
|
+
* - `statusLine`: generic Claude Code setting — only written when absent or when
|
|
168
|
+
* the existing one is AQE's own (so a user's custom status line is preserved).
|
|
169
|
+
* - `includeCoAuthoredBy`: generic Claude Code setting — only written when the
|
|
170
|
+
* user has not set it explicitly (respects an intentional `false`).
|
|
171
|
+
* - `aqe` / `v3Configuration` / `v3Learning`: AQE-owned sections, deep-merged so
|
|
172
|
+
* AQE values are refreshed while any user-added keys survive.
|
|
173
|
+
*
|
|
174
|
+
* Mutates and returns `settings`.
|
|
175
|
+
*/
|
|
176
|
+
export function applyV3Sections(settings, sections) {
|
|
177
|
+
for (const [key, value] of Object.entries(sections)) {
|
|
178
|
+
if (key === '_aqePermissions') {
|
|
179
|
+
const existingPerms = settings.permissions || {};
|
|
180
|
+
const existingAllow = existingPerms.allow || [];
|
|
181
|
+
const merged = [...new Set([...existingAllow, ...value])];
|
|
182
|
+
settings.permissions = { ...existingPerms, allow: merged };
|
|
183
|
+
}
|
|
184
|
+
else if (key === 'statusLine') {
|
|
185
|
+
// Preserve a user's (or another tool's) custom status line.
|
|
186
|
+
if (settings.statusLine === undefined || isAqeStatusLine(settings.statusLine)) {
|
|
187
|
+
settings.statusLine = value;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (key === 'includeCoAuthoredBy') {
|
|
191
|
+
// Respect an explicit user choice; only set the default when unset.
|
|
192
|
+
if (settings.includeCoAuthoredBy === undefined) {
|
|
193
|
+
settings.includeCoAuthoredBy = value;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
// AQE-owned section — deep-merge so user additions are not dropped.
|
|
198
|
+
settings[key] = deepMergeOwned(settings[key], value);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return settings;
|
|
202
|
+
}
|
|
88
203
|
/**
|
|
89
204
|
* Generate v3-specific settings sections for settings.json.
|
|
90
205
|
* These sections enable the self-learning system, status line, and permissions.
|
|
@@ -441,6 +441,13 @@ export function isHyperbolicHnswEnabled() {
|
|
|
441
441
|
*/
|
|
442
442
|
export function initFeatureFlagsFromEnv() {
|
|
443
443
|
const envFlags = {};
|
|
444
|
+
// RVF-backed PatternStore (ADR-066). Was the only flag WITHOUT an env override,
|
|
445
|
+
// so an environment where RVF native init fails (e.g. `RVF error 0x0303:
|
|
446
|
+
// FsyncFailed` on a macOS virtiofs bind mount) had no runtime way to fall back
|
|
447
|
+
// to the SQLite HNSW PatternStore. Set RUVECTOR_USE_RVF_PATTERN_STORE=false there.
|
|
448
|
+
if (process.env.RUVECTOR_USE_RVF_PATTERN_STORE !== undefined) {
|
|
449
|
+
envFlags.useRVFPatternStore = process.env.RUVECTOR_USE_RVF_PATTERN_STORE === 'true';
|
|
450
|
+
}
|
|
444
451
|
if (process.env.RUVECTOR_USE_SONA !== undefined) {
|
|
445
452
|
envFlags.useQESONA = process.env.RUVECTOR_USE_SONA === 'true';
|
|
446
453
|
}
|
|
@@ -37,6 +37,12 @@ export interface PatternLifecycleConfig {
|
|
|
37
37
|
promotionActivityWindowDays: number;
|
|
38
38
|
/** ADR-061: Asymmetric learning config */
|
|
39
39
|
asymmetricLearning: Partial<AsymmetricLearningConfig>;
|
|
40
|
+
/**
|
|
41
|
+
* ADR-121: allow `judge:llm`-tier evidence to promote patterns. A single LLM
|
|
42
|
+
* judgment is noisy (ADR-119), so judge-tier promotion is an explicit,
|
|
43
|
+
* cost-bearing opt-in. Default false — only `oracle:test-exec` promotes.
|
|
44
|
+
*/
|
|
45
|
+
allowJudgeTierPromotion: boolean;
|
|
40
46
|
}
|
|
41
47
|
/**
|
|
42
48
|
* Default lifecycle configuration
|
|
@@ -103,6 +109,10 @@ export interface PromotionCheckResult {
|
|
|
103
109
|
currentReward: number;
|
|
104
110
|
currentOccurrences: number;
|
|
105
111
|
currentSuccessRate: number;
|
|
112
|
+
/** ADR-121: evidence tier of the pattern (gates promotion). */
|
|
113
|
+
provenanceTier: string;
|
|
114
|
+
/** ADR-121: whether the pattern's evidence tier is strong enough to promote. */
|
|
115
|
+
meetsProvenanceTier: boolean;
|
|
106
116
|
}
|
|
107
117
|
/**
|
|
108
118
|
* Result of deprecation check
|
|
@@ -178,6 +188,12 @@ export declare class PatternLifecycleManager {
|
|
|
178
188
|
* Generate template content from experience aggregate
|
|
179
189
|
*/
|
|
180
190
|
private generateTemplateContent;
|
|
191
|
+
/**
|
|
192
|
+
* ADR-121: read a pattern's provenance tier. Tolerant of an un-migrated DB
|
|
193
|
+
* (column absent) and of a NULL/unknown value — both degrade to the
|
|
194
|
+
* conservative default so the gate can never be bypassed by a missing tier.
|
|
195
|
+
*/
|
|
196
|
+
private getProvenanceTier;
|
|
181
197
|
/**
|
|
182
198
|
* Check if a pattern should be promoted
|
|
183
199
|
*/
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
import { PROMOTION_THRESHOLD } from './qe-patterns.js';
|
|
12
12
|
import { AsymmetricLearningEngine } from './asymmetric-learning.js';
|
|
13
13
|
import { safeJsonParse } from '../shared/safe-json.js';
|
|
14
|
+
import { tierAllowsPromotion, DEFAULT_PROVENANCE_TIER } from './provenance-tier.js';
|
|
15
|
+
import { reExecutePathGate, pathGateFingerprint, pathSealedHash, verifyPathPromotion, } from '../validation/gate-reexecute.js';
|
|
14
16
|
import { LoggerFactory } from '../logging/index.js';
|
|
15
17
|
import { isTemporalCompressionEnabled } from '../integrations/ruvector/feature-flags.js';
|
|
16
18
|
const logger = LoggerFactory.create('pattern-lifecycle');
|
|
@@ -28,6 +30,7 @@ export const DEFAULT_LIFECYCLE_CONFIG = {
|
|
|
28
30
|
maxAgeForActivePatterns: 90,
|
|
29
31
|
promotionActivityWindowDays: 30,
|
|
30
32
|
asymmetricLearning: {},
|
|
33
|
+
allowJudgeTierPromotion: false,
|
|
31
34
|
};
|
|
32
35
|
// ============================================================================
|
|
33
36
|
// EWC++ catastrophic-forgetting protection (#510 item 6)
|
|
@@ -143,6 +146,23 @@ export class PatternLifecycleManager {
|
|
|
143
146
|
`);
|
|
144
147
|
console.log('[PatternLifecycle] Added promotion_date column to qe_patterns');
|
|
145
148
|
}
|
|
149
|
+
// ADR-121: provenance_tier — additive, conservative-default migration.
|
|
150
|
+
// The DEFAULT backfills every existing row as 'proxy:structural', which can
|
|
151
|
+
// never over-credit legacy history. Rows re-derived from execution evidence
|
|
152
|
+
// are re-tiered upward through the normal write path (never up-tiered here).
|
|
153
|
+
// Distinct from the lifecycle `tier` (short-term/long-term) column.
|
|
154
|
+
try {
|
|
155
|
+
this.db.prepare(`
|
|
156
|
+
SELECT provenance_tier FROM qe_patterns LIMIT 1
|
|
157
|
+
`).get();
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
logger.debug('Adding missing provenance_tier column', { error: e instanceof Error ? e.message : String(e) });
|
|
161
|
+
this.db.exec(`
|
|
162
|
+
ALTER TABLE qe_patterns ADD COLUMN provenance_tier TEXT DEFAULT '${DEFAULT_PROVENANCE_TIER}'
|
|
163
|
+
`);
|
|
164
|
+
console.log(`[PatternLifecycle] Added provenance_tier column to qe_patterns (backfilled '${DEFAULT_PROVENANCE_TIER}')`);
|
|
165
|
+
}
|
|
146
166
|
}
|
|
147
167
|
// ============================================================================
|
|
148
168
|
// Experience Extraction
|
|
@@ -344,6 +364,20 @@ Pattern extracted from ${exp.count} successful experiences.`;
|
|
|
344
364
|
// ============================================================================
|
|
345
365
|
// Pattern Promotion
|
|
346
366
|
// ============================================================================
|
|
367
|
+
/**
|
|
368
|
+
* ADR-121: read a pattern's provenance tier. Tolerant of an un-migrated DB
|
|
369
|
+
* (column absent) and of a NULL/unknown value — both degrade to the
|
|
370
|
+
* conservative default so the gate can never be bypassed by a missing tier.
|
|
371
|
+
*/
|
|
372
|
+
getProvenanceTier(patternId) {
|
|
373
|
+
try {
|
|
374
|
+
const row = this.db.prepare(`SELECT provenance_tier FROM qe_patterns WHERE id = ?`).get(patternId);
|
|
375
|
+
return row?.provenance_tier ?? DEFAULT_PROVENANCE_TIER;
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
return DEFAULT_PROVENANCE_TIER;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
347
381
|
/**
|
|
348
382
|
* Check if a pattern should be promoted
|
|
349
383
|
*/
|
|
@@ -359,23 +393,35 @@ Pattern extracted from ${exp.count} successful experiences.`;
|
|
|
359
393
|
currentReward: 0,
|
|
360
394
|
currentOccurrences: 0,
|
|
361
395
|
currentSuccessRate: 0,
|
|
396
|
+
provenanceTier: DEFAULT_PROVENANCE_TIER,
|
|
397
|
+
meetsProvenanceTier: false,
|
|
362
398
|
};
|
|
363
399
|
}
|
|
364
400
|
const avgReward = pattern.qualityScore;
|
|
365
401
|
const meetsReward = avgReward >= this.config.promotionRewardThreshold;
|
|
366
402
|
const meetsOccurrences = pattern.usageCount >= this.config.promotionMinOccurrences;
|
|
367
403
|
const meetsSuccessRate = pattern.successRate >= this.config.promotionMinSuccessRate;
|
|
404
|
+
// ADR-121: evidence-tier gate. Only oracle:test-exec (or judge:llm under an
|
|
405
|
+
// explicit budget flag) may promote; proxy:structural is never auto-promoted.
|
|
406
|
+
// Read the tier directly — the column is additive and may be absent on an
|
|
407
|
+
// un-migrated DB, in which case it defaults to the conservative tier.
|
|
408
|
+
const provenanceTier = this.getProvenanceTier(patternId);
|
|
409
|
+
const meetsProvenanceTier = tierAllowsPromotion(provenanceTier, {
|
|
410
|
+
allowJudgeTier: this.config.allowJudgeTierPromotion,
|
|
411
|
+
});
|
|
368
412
|
// Temporal window: require activity within configured window to prevent
|
|
369
413
|
// promoting stale patterns that haven't been validated recently
|
|
370
414
|
const PROMOTION_ACTIVITY_WINDOW_MS = this.config.promotionActivityWindowDays * 24 * 60 * 60 * 1000;
|
|
371
415
|
const lastActivity = pattern.lastUsedAt?.getTime() ?? pattern.createdAt.getTime();
|
|
372
416
|
const meetsActivityWindow = (Date.now() - lastActivity) < PROMOTION_ACTIVITY_WINDOW_MS;
|
|
373
417
|
return {
|
|
374
|
-
shouldPromote: pattern.tier === 'short-term' && meetsReward && meetsOccurrences && meetsSuccessRate && meetsActivityWindow,
|
|
418
|
+
shouldPromote: pattern.tier === 'short-term' && meetsProvenanceTier && meetsReward && meetsOccurrences && meetsSuccessRate && meetsActivityWindow,
|
|
375
419
|
meetsRewardThreshold: meetsReward,
|
|
376
420
|
meetsOccurrenceThreshold: meetsOccurrences,
|
|
377
421
|
meetsSuccessRateThreshold: meetsSuccessRate,
|
|
378
422
|
meetsActivityWindow,
|
|
423
|
+
provenanceTier,
|
|
424
|
+
meetsProvenanceTier,
|
|
379
425
|
currentReward: avgReward,
|
|
380
426
|
currentOccurrences: pattern.usageCount,
|
|
381
427
|
currentSuccessRate: pattern.successRate,
|
|
@@ -389,6 +435,36 @@ Pattern extracted from ${exp.count} successful experiences.`;
|
|
|
389
435
|
if (!check.shouldPromote) {
|
|
390
436
|
return false;
|
|
391
437
|
}
|
|
438
|
+
// ADR-120: re-execute the frozen `pattern-promote/v1` rule on the sealed
|
|
439
|
+
// check result before writing. `checkPromotion` is advisory; the frozen
|
|
440
|
+
// rule is authoritative. A forged/stale promote (proxy-tier or sub-threshold
|
|
441
|
+
// inputs logged as `promote`) fails `verifyPathPromotion` and the UPDATE is
|
|
442
|
+
// skipped — the same defense the flywheel accept path gets (ADR-120 §5).
|
|
443
|
+
const sealed = {
|
|
444
|
+
provenanceTier: check.provenanceTier,
|
|
445
|
+
allowJudgeTier: this.config.allowJudgeTierPromotion,
|
|
446
|
+
reward: check.currentReward,
|
|
447
|
+
rewardThreshold: this.config.promotionRewardThreshold,
|
|
448
|
+
occurrences: check.currentOccurrences,
|
|
449
|
+
occurrenceThreshold: this.config.promotionMinOccurrences,
|
|
450
|
+
successRate: check.currentSuccessRate,
|
|
451
|
+
successRateThreshold: this.config.promotionMinSuccessRate,
|
|
452
|
+
withinActivityWindow: check.meetsActivityWindow,
|
|
453
|
+
};
|
|
454
|
+
const rerun = reExecutePathGate('pattern-promote/v1', sealed);
|
|
455
|
+
const receipt = {
|
|
456
|
+
ruleVersion: 'pattern-promote/v1',
|
|
457
|
+
ruleFingerprint: pathGateFingerprint('pattern-promote/v1'),
|
|
458
|
+
sealedHash: pathSealedHash(sealed),
|
|
459
|
+
sealed,
|
|
460
|
+
recordedVerdict: rerun.promote ? 'promote' : 'reject',
|
|
461
|
+
};
|
|
462
|
+
const verdict = verifyPathPromotion(receipt);
|
|
463
|
+
if (!verdict.valid || !rerun.promote) {
|
|
464
|
+
// The advisory verdict is not reproducible under the frozen rule — refuse.
|
|
465
|
+
console.warn(`[PatternLifecycle] Refusing to promote ${patternId}: ${rerun.reason} (${verdict.reason})`);
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
392
468
|
this.db.prepare(`
|
|
393
469
|
UPDATE qe_patterns
|
|
394
470
|
SET tier = 'long-term',
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance tiers for learning writes (ADR-121).
|
|
3
|
+
*
|
|
4
|
+
* Every learning write carries an explicit evidence tier. Authority tracks
|
|
5
|
+
* evidence strength: an execution-observed outcome is ground truth, an LLM
|
|
6
|
+
* judgment is a noisy opinion (ADR-119), a structural/co-occurrence inference
|
|
7
|
+
* is a weak guess. Only `oracle:test-exec` (or an explicitly-budgeted
|
|
8
|
+
* `judge:llm`) may change fleet behavior; `proxy:structural` is written and
|
|
9
|
+
* searchable but never auto-promoted.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors ruflo ADR-174's in-code tier gate (not prose). Shared across every
|
|
12
|
+
* promotion path (pattern promotion, dream apply, flywheel accept) so the gate
|
|
13
|
+
* is defined once.
|
|
14
|
+
*/
|
|
15
|
+
/** Evidence tiers, strongest first. */
|
|
16
|
+
export type ProvenanceTier = 'oracle:test-exec' | 'judge:llm' | 'proxy:structural';
|
|
17
|
+
/** Ordered strongest → weakest. Index is the rank (0 = strongest). */
|
|
18
|
+
export declare const PROVENANCE_TIERS: readonly ProvenanceTier[];
|
|
19
|
+
/**
|
|
20
|
+
* Conservative default for undifferentiated / legacy / unknown writes.
|
|
21
|
+
* The backfill (ADR-121 §4) tags all pre-existing rows with this — it can
|
|
22
|
+
* never over-credit, only under-credit until a row is re-derived from
|
|
23
|
+
* execution evidence through the normal write path.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEFAULT_PROVENANCE_TIER: ProvenanceTier;
|
|
26
|
+
/** Rank of a tier (0 = strongest). Unknown tiers rank as the weakest. */
|
|
27
|
+
export declare function tierRank(tier: string | null | undefined): number;
|
|
28
|
+
/**
|
|
29
|
+
* Normalize any raw value read from storage into a known tier.
|
|
30
|
+
* Null / undefined / unrecognized → the conservative default. Never throws —
|
|
31
|
+
* a bad tier must degrade to "weak", never crash the promotion path.
|
|
32
|
+
*/
|
|
33
|
+
export declare function coerceTier(raw: string | null | undefined): ProvenanceTier;
|
|
34
|
+
export interface PromotionTierOptions {
|
|
35
|
+
/**
|
|
36
|
+
* When true, `judge:llm`-tier evidence may promote. This is an explicit,
|
|
37
|
+
* cost-bearing budget decision (ADR-121 §2 / ADR-119): a single LLM judgment
|
|
38
|
+
* is noisy, so judge-tier promotion is opt-in, never the default.
|
|
39
|
+
*/
|
|
40
|
+
allowJudgeTier?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The in-code promotion gate (ADR-121 §2). `oracle:test-exec` may always
|
|
44
|
+
* promote; `judge:llm` promotes only under an explicit budget flag;
|
|
45
|
+
* `proxy:structural` is NEVER auto-promoted.
|
|
46
|
+
*
|
|
47
|
+
* This is the single authority consulted by every promotion path. It does not
|
|
48
|
+
* decide whether the *metrics* clear threshold — only whether the *evidence
|
|
49
|
+
* tier* is strong enough to be allowed to change fleet behavior at all.
|
|
50
|
+
*/
|
|
51
|
+
export declare function tierAllowsPromotion(tier: string | null | undefined, options?: PromotionTierOptions): boolean;
|
|
52
|
+
//# sourceMappingURL=provenance-tier.d.ts.map
|