agentic-qe 3.11.5 → 3.12.0
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 +52 -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-6IWRIHF3.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-CSTBLNYZ.js → agent-booster-wasm-IO54X6IQ.js} +2 -2
- package/dist/cli/chunks/{agent-handler-M4W4GTXN.js → agent-handler-A57SZUCW.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-VGXFYLSQ.js → agent-memory-branch-BX7LRFGN.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-FSF5U67K.js +2 -0
- package/dist/cli/chunks/{arena-FKSD3LLM.js → arena-UTC4YY6Y.js} +4 -4
- package/dist/cli/chunks/{arena-IQBRGWAG.js → arena-Y3XTX6O7.js} +2 -2
- package/dist/cli/chunks/{audit-7NSGRR4Z.js → audit-L4RL2AOY.js} +3 -3
- package/dist/cli/chunks/base-2CKCJU3O.js +2 -0
- package/dist/cli/chunks/{hnswlib-node-E6NSZPP2.js → better-sqlite3-LRDXKYOJ.js} +2 -2
- package/dist/cli/chunks/{brain-handler-M6A3UB66.js → brain-handler-OHDPI5TQ.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-2JGKY4BB.js → branch-enumerator-ZRXE2CQ7.js} +2 -2
- package/dist/cli/chunks/{browser-J43WQPJL.js → browser-NT33FG76.js} +2 -2
- package/dist/cli/chunks/browser-workflow-UGYJE64S.js +2 -0
- package/dist/cli/chunks/{chunk-JDSHUECG.js → chunk-27JCWG5J.js} +2 -2
- package/dist/cli/chunks/{chunk-B2VBDMDI.js → chunk-2ALNNXFF.js} +2 -2
- package/dist/cli/chunks/{chunk-SK754ZSH.js → chunk-2AOOIAW3.js} +4 -4
- package/dist/cli/chunks/{chunk-ZG5UAEEO.js → chunk-2AR4B3DI.js} +2 -2
- package/dist/cli/chunks/{chunk-GODAWJMZ.js → chunk-2KHDGC7N.js} +2 -2
- package/dist/cli/chunks/{chunk-YZSTZUGJ.js → chunk-2UMCB7AH.js} +1 -1
- package/dist/cli/chunks/{chunk-Q5TR6ETB.js → chunk-335GHVJV.js} +3 -3
- package/dist/cli/chunks/{chunk-UBI2EOS3.js → chunk-36MPDANH.js} +1 -1
- package/dist/cli/chunks/{chunk-C4EZNOWK.js → chunk-3AFNXU45.js} +1 -1
- package/dist/cli/chunks/{chunk-7YSBATSN.js → chunk-3B4XXFKD.js} +2 -2
- package/dist/cli/chunks/{chunk-DPL762HU.js → chunk-4GU656WM.js} +1 -1
- package/dist/cli/chunks/{chunk-I3NWKPXJ.js → chunk-4SALW7OT.js} +2 -2
- package/dist/cli/chunks/{chunk-7BCRULCP.js → chunk-5FR5GBUT.js} +2 -2
- package/dist/cli/chunks/{chunk-4XJ2A3HY.js → chunk-5VBPIJUZ.js} +4 -4
- package/dist/cli/chunks/chunk-5XFX25AJ.js +4 -0
- package/dist/cli/chunks/{chunk-UORTQXJ2.js → chunk-5YGESYBC.js} +1 -1
- package/dist/cli/chunks/{chunk-ABU64UWB.js → chunk-62RELCU6.js} +1 -1
- package/dist/cli/chunks/{chunk-2XQHG56O.js → chunk-64M3FFM4.js} +2 -2
- package/dist/cli/chunks/{chunk-K4I7UIU5.js → chunk-6JNNZGI2.js} +1 -1
- package/dist/cli/chunks/{chunk-XT4TDLOB.js → chunk-6X3RJBA3.js} +2 -2
- package/dist/cli/chunks/{chunk-JATLFS6A.js → chunk-72VZGAMJ.js} +1 -1
- package/dist/cli/chunks/{chunk-AGJOGUP5.js → chunk-7F7U2HUH.js} +1 -1
- package/dist/cli/chunks/{chunk-ZPP57WQU.js → chunk-7HJHXSYT.js} +2 -2
- package/dist/cli/chunks/{chunk-6T65OKUM.js → chunk-7WX3MKRS.js} +2 -2
- package/dist/cli/chunks/{chunk-5WMU7XCF.js → chunk-7ZIVDGSN.js} +1 -1
- package/dist/cli/chunks/{chunk-M6FW56MV.js → chunk-AAATFEIL.js} +2 -2
- package/dist/cli/chunks/{chunk-2XPMATEK.js → chunk-AEX75YGI.js} +2 -2
- package/dist/cli/chunks/chunk-BA6U7NSR.js +2 -0
- package/dist/cli/chunks/{chunk-4QOI5JS7.js → chunk-BB4OVXWF.js} +1 -1
- package/dist/cli/chunks/{chunk-K4C25BWV.js → chunk-BBC526PL.js} +2 -2
- package/dist/cli/chunks/{chunk-354367AP.js → chunk-BGRJZH5Q.js} +2 -2
- package/dist/cli/chunks/{chunk-7KXPNNMR.js → chunk-BUYPRUNY.js} +2 -2
- package/dist/cli/chunks/{chunk-O7J54OHN.js → chunk-BZPF6GTL.js} +1 -1
- package/dist/cli/chunks/{chunk-NCSXLMDL.js → chunk-C4SZSPXY.js} +2 -2
- package/dist/cli/chunks/{chunk-YBPLJRVT.js → chunk-C6GYLCTX.js} +2 -2
- package/dist/cli/chunks/{chunk-53YOYZW5.js → chunk-CC5G3K4X.js} +2 -2
- package/dist/cli/chunks/{chunk-UBY322ED.js → chunk-CHO54B34.js} +2 -2
- package/dist/cli/chunks/{chunk-EK3HPH6A.js → chunk-CMGYUCM7.js} +1 -1
- package/dist/cli/chunks/{chunk-W72FJA2H.js → chunk-CSEEGX5T.js} +2 -2
- package/dist/cli/chunks/{chunk-OS2HHJTM.js → chunk-CVGXB7IX.js} +2 -2
- package/dist/cli/chunks/{chunk-SE3JFUKP.js → chunk-DQDFACYW.js} +1 -1
- package/dist/cli/chunks/chunk-DR7PCO3S.js +153 -0
- package/dist/cli/chunks/{chunk-4MHN7JWC.js → chunk-DTOE3NYW.js} +2 -2
- package/dist/cli/chunks/{chunk-FGD6HINU.js → chunk-DXOMRWDC.js} +1 -1
- package/dist/cli/chunks/{chunk-3V36WMIO.js → chunk-EGH3H7QO.js} +1 -1
- package/dist/cli/chunks/{chunk-52U5BFZP.js → chunk-EM2JIIAQ.js} +2 -2
- package/dist/cli/chunks/{chunk-ZLBY25MB.js → chunk-ESDGCTC4.js} +1 -1
- package/dist/cli/chunks/{chunk-MTBGOWJA.js → chunk-EZE2HRQB.js} +2 -2
- package/dist/cli/chunks/{chunk-KVVJVMDM.js → chunk-FEEMJDUF.js} +2 -2
- package/dist/cli/chunks/{chunk-JBKZ5TUM.js → chunk-FI5SSLEF.js} +2 -2
- package/dist/cli/chunks/{chunk-J5XDKVI7.js → chunk-FKPUPQQT.js} +2 -2
- package/dist/cli/chunks/{chunk-URP75DL4.js → chunk-FOPS6DRZ.js} +1 -1
- package/dist/cli/chunks/{chunk-GW6XWMX2.js → chunk-FU5RNEXV.js} +2 -2
- package/dist/cli/chunks/{chunk-3JF5A72M.js → chunk-FZIHOMGY.js} +2 -2
- package/dist/cli/chunks/{chunk-AOQYORVA.js → chunk-FZRU73M4.js} +2 -2
- package/dist/cli/chunks/{chunk-MEIU7457.js → chunk-G5JQLUUO.js} +2 -2
- package/dist/cli/chunks/{chunk-MHMQ6MCT.js → chunk-G6LR7FK7.js} +2 -2
- package/dist/cli/chunks/{chunk-J6PFPY7V.js → chunk-G6RKUEGL.js} +2 -2
- package/dist/cli/chunks/{chunk-EEKG35K5.js → chunk-GCF42L7M.js} +3 -3
- package/dist/cli/chunks/{chunk-OS62Y77J.js → chunk-GGMQOEZZ.js} +2 -2
- package/dist/cli/chunks/{chunk-QKK7VBVB.js → chunk-HAEUPIKW.js} +2 -2
- package/dist/cli/chunks/{chunk-4RTWPR3X.js → chunk-HDJMD6UH.js} +1 -1
- package/dist/cli/chunks/{chunk-EDOGRFAG.js → chunk-HW62TB4T.js} +1 -1
- package/dist/cli/chunks/{chunk-LOE2JETO.js → chunk-I6WHYRWB.js} +2 -2
- package/dist/cli/chunks/{chunk-VMFAANWX.js → chunk-ICK3B24H.js} +2 -2
- package/dist/cli/chunks/{chunk-C5C4W572.js → chunk-IDLNLSQI.js} +2 -2
- package/dist/cli/chunks/{chunk-PVDXNQPL.js → chunk-IJUYHIKN.js} +2 -2
- package/dist/cli/chunks/{chunk-3WR35GFF.js → chunk-IKVNYK7Y.js} +2 -2
- package/dist/cli/chunks/{chunk-62OTU2AP.js → chunk-JOBCMNTP.js} +2 -2
- package/dist/cli/chunks/{chunk-BJLA2IX7.js → chunk-JYX7AZHE.js} +2 -2
- package/dist/cli/chunks/{chunk-6Q57K4YD.js → chunk-JYXSVSH2.js} +2 -2
- package/dist/cli/chunks/{chunk-CKOF27L7.js → chunk-K5SN66B4.js} +2 -2
- package/dist/cli/chunks/{chunk-PW72M2FE.js → chunk-KDLYTJ5C.js} +2 -2
- package/dist/cli/chunks/{chunk-4LODYRNV.js → chunk-KI5BP4X5.js} +2 -2
- package/dist/cli/chunks/{chunk-CDJP6COA.js → chunk-KJWQ7ENF.js} +2 -2
- package/dist/cli/chunks/{chunk-FII3WCCY.js → chunk-KN5GOEYK.js} +2 -2
- package/dist/cli/chunks/{chunk-7DTMENY6.js → chunk-KZ37VHMJ.js} +2 -2
- package/dist/cli/chunks/{chunk-I3ANRYQ6.js → chunk-KZMRU7DL.js} +2 -2
- package/dist/cli/chunks/{chunk-YFCULQBP.js → chunk-L5ZLOW3K.js} +2 -2
- package/dist/cli/chunks/{chunk-37ZUF5NX.js → chunk-LMJUQWR7.js} +1 -1
- package/dist/cli/chunks/{chunk-HJWT4KME.js → chunk-MBF3Q7FQ.js} +1 -1
- package/dist/cli/chunks/chunk-MDT3LIXS.js +2 -0
- package/dist/cli/chunks/{chunk-3LY7OCSO.js → chunk-MJPYNGZ7.js} +1 -1
- package/dist/cli/chunks/{chunk-SO6G4IX3.js → chunk-MK3J7JVZ.js} +2 -2
- package/dist/cli/chunks/{chunk-VN2HHBZN.js → chunk-MUAHFGIX.js} +2 -2
- package/dist/cli/chunks/{chunk-6R3YOAKO.js → chunk-MUV56BPK.js} +2 -2
- package/dist/cli/chunks/{chunk-XLT3FYS7.js → chunk-NLHISTL2.js} +2 -2
- package/dist/cli/chunks/{chunk-26WEI3P4.js → chunk-NNGCUJWQ.js} +2 -2
- package/dist/cli/chunks/{chunk-W7TYKPLY.js → chunk-NW7G57NR.js} +2 -2
- package/dist/cli/chunks/{chunk-Y6DWJKHU.js → chunk-O3C5RRDQ.js} +3 -3
- package/dist/cli/chunks/{chunk-TEIWJ3GJ.js → chunk-OHSVDMF7.js} +1 -1
- package/dist/cli/chunks/{chunk-KP3R2M2G.js → chunk-OPIWFXME.js} +1 -1
- package/dist/cli/chunks/{chunk-FGSIID5C.js → chunk-P52YORQG.js} +2 -2
- package/dist/cli/chunks/chunk-PM566XEO.js +2 -0
- package/dist/cli/chunks/chunk-POKMJTD2.js +2 -0
- package/dist/cli/chunks/{chunk-HC6KTVFR.js → chunk-PQMLIVGV.js} +2 -2
- package/dist/cli/chunks/{chunk-RJN2RM76.js → chunk-PT3FTGKZ.js} +2 -2
- package/dist/cli/chunks/{chunk-ZXEWTZFR.js → chunk-Q5YRPS4P.js} +1 -1
- package/dist/cli/chunks/{chunk-AL5VJJN4.js → chunk-QJ6H2HQQ.js} +1 -1
- package/dist/cli/chunks/{chunk-AXKWV5NF.js → chunk-RG552ROA.js} +3 -3
- package/dist/cli/chunks/{chunk-RKXZLTWR.js → chunk-RHC7TFPU.js} +2 -2
- package/dist/cli/chunks/{chunk-RFLHPLET.js → chunk-RMFRFING.js} +1 -1
- package/dist/cli/chunks/{chunk-WMZ2QGGS.js → chunk-RQN4HWGV.js} +2 -2
- package/dist/cli/chunks/{chunk-3I4TCMOJ.js → chunk-RYUSZ43T.js} +1 -1
- package/dist/cli/chunks/{chunk-BTLUWH4R.js → chunk-RZDNCTOA.js} +2 -2
- package/dist/cli/chunks/chunk-SCMXIBI7.js +2 -0
- package/dist/cli/chunks/{chunk-FMNXHVIN.js → chunk-SPEUF7ZL.js} +2 -2
- package/dist/cli/chunks/{chunk-IU5RSN6M.js → chunk-SSXAW3ER.js} +2 -2
- package/dist/cli/chunks/{chunk-WPSK237F.js → chunk-TC2JE5OK.js} +3 -3
- package/dist/cli/chunks/{chunk-DFRRWOEX.js → chunk-TED4KOSK.js} +2 -2
- package/dist/cli/chunks/{chunk-SUL3I6QZ.js → chunk-TJ6N4CCX.js} +2 -2
- package/dist/cli/chunks/{chunk-Y25PO65W.js → chunk-TJEJ4UVX.js} +2 -2
- package/dist/cli/chunks/{chunk-G2ZIJZJ7.js → chunk-TO5PQSDD.js} +2 -2
- package/dist/cli/chunks/{chunk-MMEXHZUC.js → chunk-TR5GOGH3.js} +5 -5
- package/dist/cli/chunks/{chunk-OGNTCZKK.js → chunk-UGJQJSPB.js} +1 -1
- package/dist/cli/chunks/{chunk-AF6P5RWY.js → chunk-USB44IHJ.js} +2 -2
- package/dist/cli/chunks/{chunk-DLBVADWQ.js → chunk-UUOXV3NS.js} +42 -42
- package/dist/cli/chunks/chunk-UVVKFBF7.js +2 -0
- package/dist/cli/chunks/{chunk-FIPKIIMS.js → chunk-V2MD5EDD.js} +2 -2
- package/dist/cli/chunks/{chunk-DVW66FPU.js → chunk-VA7TEOPM.js} +1 -1
- package/dist/cli/chunks/{chunk-MCHEUSY4.js → chunk-VMP4M5PB.js} +1 -1
- package/dist/cli/chunks/{chunk-4Y3LGBKJ.js → chunk-VS4GMNJK.js} +3 -3
- package/dist/cli/chunks/{chunk-XKQY2Z3Q.js → chunk-VWJSWXHG.js} +1 -1
- package/dist/cli/chunks/{chunk-LPR2R3AN.js → chunk-VZ67ZDB3.js} +3 -3
- package/dist/cli/chunks/{chunk-TTJJ4DQE.js → chunk-W2OMW6UU.js} +2 -2
- package/dist/cli/chunks/{chunk-62UM7Q5N.js → chunk-W766S4SK.js} +1 -1
- package/dist/cli/chunks/{chunk-7P6X4BFO.js → chunk-WJYTLRA5.js} +3 -3
- package/dist/cli/chunks/{chunk-AOXJFDH5.js → chunk-WNASEUBW.js} +10 -10
- package/dist/cli/chunks/{chunk-YGVDP6X7.js → chunk-WT4ZDDFM.js} +1 -1
- package/dist/cli/chunks/{chunk-IBDQWKI3.js → chunk-XEYW3V5I.js} +2 -2
- package/dist/cli/chunks/{chunk-BLPWJQTY.js → chunk-XIFPIVZI.js} +2 -2
- package/dist/cli/chunks/{chunk-D45QLJEL.js → chunk-Y2MCIIJD.js} +1 -1
- package/dist/cli/chunks/{chunk-WHHQIL4F.js → chunk-YKOTOCO6.js} +2 -2
- package/dist/cli/chunks/{chunk-TRNBQFFG.js → chunk-Z3W3R4CW.js} +2 -2
- package/dist/cli/chunks/{chunk-KQVIWE3W.js → chunk-ZT2WHCVM.js} +2 -2
- package/dist/cli/chunks/{chunk-TBT3OFRW.js → chunk-ZVPAFX4I.js} +2 -2
- package/dist/cli/chunks/{chunk-VMWRMINE.js → chunk-ZWC6CM4R.js} +1 -1
- package/dist/cli/chunks/{ci-CBNVLOOQ.js → ci-RJH5LAL3.js} +2 -2
- package/dist/cli/chunks/{ci-output-I4HY2FYJ.js → ci-output-62SGMGB2.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-5VRBKGWL.js → circuit-breaker-QXTS5ZAW.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-XPJPKHIO.js → claude-flow-setup-BBCCT5WV.js} +2 -2
- package/dist/cli/chunks/client-E2XUBCLK.js +2 -0
- package/dist/cli/chunks/{cline-installer-OFRDUUWZ.js → cline-installer-IZCUJJ3I.js} +2 -2
- package/dist/cli/chunks/{code-QIZQVB3E.js → code-AWNVOZ7S.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-LMUUWEX4.js → code-index-extractor-MX65BKMI.js} +2 -2
- package/dist/cli/chunks/{codex-installer-N2MKIZ2S.js → codex-installer-EQT6JVLM.js} +2 -2
- package/dist/cli/chunks/{completions-Y36S3C5J.js → completions-WOJAM45W.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-73YS3WUD.js → complexity-analyzer-3DJB7V3K.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-SAOTP6J3.js → continuedev-installer-P4KWUTCJ.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-A4HXF6HE.js → copilot-installer-FFZWTMWQ.js} +2 -2
- package/dist/cli/chunks/core-handlers-46Z5VOO6.js +2 -0
- package/dist/cli/chunks/{cost-tracker-P26XUVZS.js → cost-tracker-CYBOV3NI.js} +2 -2
- package/dist/cli/chunks/{coverage-HVNHSMVJ.js → coverage-GTZJBSC4.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-SXQ3HFRY.js +2 -0
- package/dist/cli/chunks/{cursor-installer-46BQFTYZ.js → cursor-installer-WZIVXGGB.js} +2 -2
- package/dist/cli/chunks/{daemon-YE7K2AZF.js → daemon-JWMHEJEN.js} +4 -4
- package/dist/cli/chunks/{daemon-Y54O3FLT.js → daemon-MSFN2LXY.js} +3 -3
- package/dist/cli/chunks/{dag-attention-scheduler-ETA7YY52.js → dag-attention-scheduler-4TWOTTQE.js} +2 -2
- package/dist/cli/chunks/{detect-5WLQ2J3E.js → detect-YZ6AGQPB.js} +2 -2
- package/dist/cli/chunks/{dist-node-45WW6I7J.js → dist-node-3EM2XH54.js} +2 -2
- package/dist/cli/chunks/{domain-handler-J7DQV74M.js → domain-handler-4XU5BINU.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-GD2EGQVR.js → domain-transfer-HUFC7I52.js} +2 -2
- package/dist/cli/chunks/dream-R6MQQQ3N.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-JELNEA2D.js → embed-and-insert-pattern-J5ZFM6YX.js} +2 -2
- package/dist/cli/chunks/{eval-A4PA5G2U.js → eval-XYOA3EH2.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-MLHTYWTA.js → experience-capture-middleware-E3RYQB6Z.js} +3 -3
- package/dist/cli/chunks/{fast-paths-QYDTITRV.js → fast-paths-DKIYN2YS.js} +2 -2
- package/dist/cli/chunks/{feature-flags-MQYYRHIK.js → feature-flags-S2RNZATS.js} +2 -2
- package/dist/cli/chunks/{feature-flags-H4MSY26Z.js → feature-flags-ZB63Z7N5.js} +2 -2
- package/dist/cli/chunks/{file-discovery-RMFVJNGL.js → file-discovery-USJJLYQU.js} +2 -2
- package/dist/cli/chunks/{fleet-7KZQOTAC.js → fleet-4MUPHSF5.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-NMZFTGVH.js → gnn-wrapper-PYOQZKX6.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-7BQDK7MG.js → heartbeat-handler-HLO5XCG7.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-OSDPJT6A.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-KMGSHBIN.js +2 -0
- package/dist/cli/chunks/hnsw-index-IMFRAOPE.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-TPPGBPKF.js → hnsw-legacy-bridge-FZEH2KLM.js} +2 -2
- package/dist/cli/chunks/{better-sqlite3-2KR4LQRU.js → hnswlib-node-VS6L5VUG.js} +2 -2
- package/dist/cli/chunks/{hooks-CYZIUYSH.js → hooks-R2757K57.js} +10 -10
- package/dist/cli/chunks/hybrid-router-57QSWSWC.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-WC6DMTYQ.js → hypergraph-engine-EAV3GJ5D.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-GTGA3TXJ.js → hypergraph-handler-5ERXAVGH.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-OC4MPBGA.js +2 -0
- package/dist/cli/chunks/{init-handler-N3Z72JNI.js → init-handler-RXUSEMG7.js} +6 -6
- package/dist/cli/chunks/init-wizard-CDBRL4PO.js +2 -0
- package/dist/cli/chunks/kernel-CQ7R3AAV.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-FUX4V6II.js → kilocode-installer-ZUBVBHGT.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-ZSNZT7ZR.js → kiro-installer-TRTRQDGL.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-UXNH7RY4.js +2 -0
- package/dist/cli/chunks/{learning-UQY64COU.js → learning-UYXWAU5D.js} +3 -3
- package/dist/cli/chunks/{llm-router-CMHGGX6N.js → llm-router-TB5OJPEV.js} +4 -4
- package/dist/cli/chunks/llm-router-service-UV34YXBE.js +2 -0
- package/dist/cli/chunks/{load-E6WH4QN2.js → load-ELPSUIPV.js} +2 -2
- package/dist/cli/chunks/load-test-2VEN3PQZ.js +2 -0
- package/dist/cli/chunks/{mcp-UM5VTW6N.js → mcp-UX7TK3XV.js} +2 -2
- package/dist/cli/chunks/{memory-7Q3XDUE5.js → memory-W3LG6H6N.js} +5 -5
- package/dist/cli/chunks/memory-backend-TZL5U6F3.js +2 -0
- package/dist/cli/chunks/memory-handlers-BNXAYS2P.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-LZENWVRR.js → multi-model-executor-227LWZRY.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-O2JAIPLF.js → opencode-installer-F4WKVWDL.js} +2 -2
- package/dist/cli/chunks/{orchestrator-DKZWXDRI.js → orchestrator-V4DBMGK6.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-KLX2RNHM.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-CLUL4M55.js → pattern-usage-recorder-BY3HEWSU.js} +2 -2
- package/dist/cli/chunks/{pipeline-2VDLTR5J.js → pipeline-3F5RIESX.js} +2 -2
- package/dist/cli/chunks/{platform-4N4Q5XYX.js → platform-KCGXTZO3.js} +2 -2
- package/dist/cli/chunks/{plugin-GY5AU5CS.js → plugin-2H552KOV.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-TQ4DKDZS.js → prime-radiant-advanced-wasm-EFKVL7VN.js} +2 -2
- package/dist/cli/chunks/protocol-executor-5HJKW6MC.js +2 -0
- package/dist/cli/chunks/{protocol-handler-T3LZ3WRG.js → protocol-handler-ELGYV7D2.js} +2 -2
- package/dist/cli/chunks/{prove-OV7S5J4W.js → prove-AYJCQYNI.js} +2 -2
- package/dist/cli/chunks/provider-manager-TRZSBXD3.js +2 -0
- package/dist/cli/chunks/qe-reasoning-bank-RCEYSLVV.js +2 -0
- package/dist/cli/chunks/{quality-AXD4NLQA.js → quality-HH7L5A7V.js} +2 -2
- package/dist/cli/chunks/quality-gate-NAQLXE4C.js +7 -0
- package/dist/cli/chunks/queen-coordinator-6JFZD54W.js +2 -0
- package/dist/cli/chunks/{real-embeddings-2PUCC7FG.js → real-embeddings-IO3F4ZFR.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-WJ5ARGLW.js → roocode-installer-X4TU5HO4.js} +2 -2
- package/dist/cli/chunks/router-KRLC46NS.js +2 -0
- package/dist/cli/chunks/routing-feedback-WW26H6SA.js +2 -0
- package/dist/cli/chunks/{routing-handler-CU6657SZ.js → routing-handler-ZJKGDDMT.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-IIF6VSFW.js → ruvector-commands-NXCSUBN2.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-YMQI7XO2.js → rvf-dual-writer-JMA74SKP.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-HDE3PR2W.js → rvf-migration-adapter-BNTGH2KU.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-MQV5OA7K.js → rvf-migration-coordinator-7T2HHUOH.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-OVQKPQUH.js +2 -0
- package/dist/cli/chunks/safe-db-UQOCQIH2.js +2 -0
- package/dist/cli/chunks/schedule-EUX7ZQUK.js +2 -0
- package/dist/cli/chunks/scheduler-MALHQKNR.js +2 -0
- package/dist/cli/chunks/{security-UM3IGDSM.js → security-XSK2QHB3.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-I3SOJ6M4.js → shared-rvf-adapter-WLRKI7RY.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-KQGC2UO7.js → shared-rvf-dual-writer-SZW3J7ZK.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-OBCLRP4L.js +2 -0
- package/dist/cli/chunks/{status-handler-OX4CJZME.js → status-handler-HGCKYJX2.js} +2 -2
- package/dist/cli/chunks/{structural-health-PYUMVBXJ.js → structural-health-4SJCFX63.js} +2 -2
- package/dist/cli/chunks/{sync-2TED3YTY.js → sync-7WAVNZGL.js} +2 -2
- package/dist/cli/chunks/{sync-VALFNTA6.js → sync-ATR4DUSA.js} +2 -2
- package/dist/cli/chunks/{task-handler-VPGAJVPC.js → task-handler-O6REL34Y.js} +2 -2
- package/dist/cli/chunks/{task-handlers-IB4UAMU6.js → task-handlers-WFV2ZYWW.js} +3 -3
- package/dist/cli/chunks/{test-OMRJOZB6.js → test-4LXUVHEU.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-ZL3YFPBU.js → test-scheduling-OTN3DMKY.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-DNWZI7SH.js → token-bootstrap-VA7T4P42.js} +2 -2
- package/dist/cli/chunks/{token-usage-IYO7RGFF.js → token-usage-TLT6OXXR.js} +2 -2
- package/dist/cli/chunks/{transformers-53ALC34T.js → transformers-JI7LZRQ3.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-WUKJ2I2Q.js → tree-sitter-wasm-parser-QNIMHB4K.js} +2 -2
- package/dist/cli/chunks/{types-47FTEPMV.js → types-DJNWOAC6.js} +2 -2
- package/dist/cli/chunks/unified-memory-A5BS3LGX.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-WJLJO5MY.js +2 -0
- package/dist/cli/chunks/unified-persistence-CFC2BKI5.js +2 -0
- package/dist/cli/chunks/{upgrade-QPLMJA5Z.js → upgrade-VEW4FL23.js} +2 -2
- package/dist/cli/chunks/{validate-3GVKZOVF.js → validate-O3P6PF7B.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-XCRTLVM6.js → validate-swarm-M2HXHZVC.js} +2 -2
- package/dist/cli/chunks/{vibium-CH4VPKVZ.js → vibium-GOU55LUO.js} +2 -2
- package/dist/cli/chunks/visual-security-VPB6KVYJ.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-JDBNAZTV.js → web-tree-sitter-MXOI4GH3.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-3MNPVJBP.js → windsurf-installer-6GKT53IH.js} +2 -2
- package/dist/cli/chunks/{witness-chain-HR5UBV5J.js → witness-chain-OXGQGL26.js} +2 -2
- package/dist/cli/chunks/witness-chain-ZZAUAXDY.js +2 -0
- package/dist/cli/chunks/{witness-key-manager-G5SQTIBZ.js → witness-key-manager-PGFSQXUJ.js} +2 -2
- package/dist/cli/chunks/{workflow-43EMD5FY.js → workflow-ENBWRMBA.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-S4LBFTYD.js +2 -0
- package/dist/cli/chunks/{wrappers-3N7AYNM3.js → wrappers-MHLNYANQ.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/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-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
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QE-policy flywheel — the generational loop (ADR-118).
|
|
3
|
+
*
|
|
4
|
+
* One generation: score the baseline champion and a candidate, seal the decision
|
|
5
|
+
* inputs, re-execute the FROZEN accept() rule (ADR-120 `accept/v1`: held-out
|
|
6
|
+
* beats baseline ∧ anchor no-regression (ADR-117) ∧ oracle tier (ADR-121)),
|
|
7
|
+
* and emit an Ed25519-signed receipt into an append-only lineage. Promotions
|
|
8
|
+
* compound: each generation re-bases on the previous promoted champion.
|
|
9
|
+
*
|
|
10
|
+
* The corpus SCORER is injected — harvesting `qe_patterns` and running retrieval
|
|
11
|
+
* + grading the anchor is the DB/model-touching part, wired separately. This
|
|
12
|
+
* keeps the loop, gate, receipts, and lineage fully testable and deterministic.
|
|
13
|
+
*
|
|
14
|
+
* Honest-null (ADR-234): a generation — or a whole run — that promotes NOTHING
|
|
15
|
+
* is a correct, valid, replayable outcome, not a failure.
|
|
16
|
+
*/
|
|
17
|
+
import type { RetrievalPolicy } from './policy.js';
|
|
18
|
+
import { type EvolveReceipt, type Signer } from './receipt.js';
|
|
19
|
+
/** Scores for a policy on the harvested corpus + the frozen anchor. */
|
|
20
|
+
export interface PolicyScores {
|
|
21
|
+
/** Self-retrieval on the held-out split (the train/serve signal — never the accept signal alone). */
|
|
22
|
+
heldOut: number;
|
|
23
|
+
/** Mean over the ADR-117 frozen anchor items (the no-regression signal). */
|
|
24
|
+
anchorMean: number;
|
|
25
|
+
}
|
|
26
|
+
/** Injected: evaluate a policy → its held-out + anchor scores. */
|
|
27
|
+
export type PolicyScorer = (policy: RetrievalPolicy) => PolicyScores | Promise<PolicyScores>;
|
|
28
|
+
export interface HeadroomResult {
|
|
29
|
+
hasHeadroom: boolean;
|
|
30
|
+
baselineHeldOut: number;
|
|
31
|
+
baselineAnchorMean: number;
|
|
32
|
+
reason: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* ADR-118 §1 headroom precondition. If the baseline already saturates the
|
|
36
|
+
* held-out signal, the loop must NOT run — it would spend compute for
|
|
37
|
+
* structurally-zero promotions (the MetaHarness SWE-bench null).
|
|
38
|
+
*/
|
|
39
|
+
export declare function checkHeadroom(baseline: RetrievalPolicy, scorer: PolicyScorer, saturation?: number): Promise<HeadroomResult>;
|
|
40
|
+
export interface GenerationInput {
|
|
41
|
+
generation: number;
|
|
42
|
+
baseline: RetrievalPolicy;
|
|
43
|
+
candidate: RetrievalPolicy;
|
|
44
|
+
scorer: PolicyScorer;
|
|
45
|
+
/** ADR-117 frozen anchor content hash (which anchor was graded). */
|
|
46
|
+
anchorHash: string;
|
|
47
|
+
/** No-regression tolerance (ADR-117 sign-off: 0.0). */
|
|
48
|
+
anchorTol: number;
|
|
49
|
+
/** Provenance tier of the corpus evidence (ADR-121). Only oracle-tier promotes. */
|
|
50
|
+
provenanceTier?: string;
|
|
51
|
+
/** Whether judge-tier promotion is explicitly budgeted (ADR-121). */
|
|
52
|
+
allowJudgeTier?: boolean;
|
|
53
|
+
signer: Signer;
|
|
54
|
+
/** Frozen rule version (default 'accept/v1'). */
|
|
55
|
+
ruleVersion?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface GenerationResult {
|
|
58
|
+
generation: number;
|
|
59
|
+
verdict: 'promote' | 'reject';
|
|
60
|
+
baselinePolicyId: string;
|
|
61
|
+
candidatePolicyId: string;
|
|
62
|
+
scores: {
|
|
63
|
+
baseline: PolicyScores;
|
|
64
|
+
candidate: PolicyScores;
|
|
65
|
+
};
|
|
66
|
+
receipt: EvolveReceipt;
|
|
67
|
+
/** The champion AFTER this generation: candidate if promoted, else baseline unchanged. */
|
|
68
|
+
champion: RetrievalPolicy;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Run one flywheel generation. Deterministic given the scorer and signer seed.
|
|
72
|
+
* Never mutates fleet state — it returns the verdict + a signed receipt; serving
|
|
73
|
+
* the champion is a separate, reversible step (serveChampion / rollback).
|
|
74
|
+
*/
|
|
75
|
+
export declare function runFlywheelGeneration(input: GenerationInput): Promise<GenerationResult>;
|
|
76
|
+
export interface LineageResult {
|
|
77
|
+
/** Number of PROMOTED generations. */
|
|
78
|
+
promotions: number;
|
|
79
|
+
/** Every promoted child re-based on its parent's promoted candidate (compounding). */
|
|
80
|
+
lineageIntact: boolean;
|
|
81
|
+
/** Every receipt's signature verifies AND its frozen gate re-executes to the recorded verdict. */
|
|
82
|
+
allReplayable: boolean;
|
|
83
|
+
reason: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Reconstruct + validate a lineage from an ordered receipt list (ADR-118 §4).
|
|
87
|
+
* Proves the chain compounds and every step is replayable — the property that
|
|
88
|
+
* makes a stub unable to launder a regression (a forged promote fails
|
|
89
|
+
* verifyPromotion; a broken chain fails lineageIntact).
|
|
90
|
+
*/
|
|
91
|
+
export declare function reconstructLineage(receipts: EvolveReceipt[]): LineageResult;
|
|
92
|
+
export interface ActivePolicy {
|
|
93
|
+
current: RetrievalPolicy;
|
|
94
|
+
currentId: string;
|
|
95
|
+
/** Rollback target — the policy served before `current`. */
|
|
96
|
+
previous: RetrievalPolicy | null;
|
|
97
|
+
previousId: string | null;
|
|
98
|
+
generation: number;
|
|
99
|
+
}
|
|
100
|
+
/** Initialize the active pointer at the gen-0 root policy. */
|
|
101
|
+
export declare function initActivePolicy(root: RetrievalPolicy): ActivePolicy;
|
|
102
|
+
/**
|
|
103
|
+
* Serve a newly-promoted champion, shifting the old current into `previous` as
|
|
104
|
+
* the rollback target (serve-then-shadow: the new policy is served, the old is
|
|
105
|
+
* retained one generation for the canary to fall back to).
|
|
106
|
+
*/
|
|
107
|
+
export declare function serveChampion(active: ActivePolicy, champion: RetrievalPolicy, generation: number): ActivePolicy;
|
|
108
|
+
/** Roll the active pointer back to its previous policy (drift-canary auto-rollback). */
|
|
109
|
+
export declare function rollback(active: ActivePolicy): ActivePolicy;
|
|
110
|
+
export interface DriftCanaryResult {
|
|
111
|
+
drifted: boolean;
|
|
112
|
+
reason: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Drift canary (ADR-118 §5, ruflo `:259-302`): re-score the served champion
|
|
116
|
+
* against its predecessor on a FRESH harvest; if EITHER the held-out or the
|
|
117
|
+
* anchor score drops below the predecessor, the promotion regressed in
|
|
118
|
+
* production and must be rolled back.
|
|
119
|
+
*/
|
|
120
|
+
export declare function checkDriftCanary(served: PolicyScores, predecessor: PolicyScores, tol?: number): DriftCanaryResult;
|
|
121
|
+
//# sourceMappingURL=generation.d.ts.map
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QE-policy flywheel — the generational loop (ADR-118).
|
|
3
|
+
*
|
|
4
|
+
* One generation: score the baseline champion and a candidate, seal the decision
|
|
5
|
+
* inputs, re-execute the FROZEN accept() rule (ADR-120 `accept/v1`: held-out
|
|
6
|
+
* beats baseline ∧ anchor no-regression (ADR-117) ∧ oracle tier (ADR-121)),
|
|
7
|
+
* and emit an Ed25519-signed receipt into an append-only lineage. Promotions
|
|
8
|
+
* compound: each generation re-bases on the previous promoted champion.
|
|
9
|
+
*
|
|
10
|
+
* The corpus SCORER is injected — harvesting `qe_patterns` and running retrieval
|
|
11
|
+
* + grading the anchor is the DB/model-touching part, wired separately. This
|
|
12
|
+
* keeps the loop, gate, receipts, and lineage fully testable and deterministic.
|
|
13
|
+
*
|
|
14
|
+
* Honest-null (ADR-234): a generation — or a whole run — that promotes NOTHING
|
|
15
|
+
* is a correct, valid, replayable outcome, not a failure.
|
|
16
|
+
*/
|
|
17
|
+
import { DEFAULT_PROVENANCE_TIER } from '../provenance-tier.js';
|
|
18
|
+
import { reExecuteGate, gateFingerprint, sealedHash, verifyPromotion, } from '../../validation/gate-reexecute.js';
|
|
19
|
+
import { policyId } from './policy.js';
|
|
20
|
+
import { signReceipt, verifyReceiptSignature, toPromotionReceipt, } from './receipt.js';
|
|
21
|
+
/**
|
|
22
|
+
* ADR-118 §1 headroom precondition. If the baseline already saturates the
|
|
23
|
+
* held-out signal, the loop must NOT run — it would spend compute for
|
|
24
|
+
* structurally-zero promotions (the MetaHarness SWE-bench null).
|
|
25
|
+
*/
|
|
26
|
+
export async function checkHeadroom(baseline, scorer, saturation = 0.999) {
|
|
27
|
+
const s = await scorer(baseline);
|
|
28
|
+
const hasHeadroom = s.heldOut < saturation;
|
|
29
|
+
return {
|
|
30
|
+
hasHeadroom,
|
|
31
|
+
baselineHeldOut: s.heldOut,
|
|
32
|
+
baselineAnchorMean: s.anchorMean,
|
|
33
|
+
reason: hasHeadroom
|
|
34
|
+
? `baseline held-out ${s.heldOut.toFixed(4)} < saturation ${saturation} — headroom exists`
|
|
35
|
+
: `baseline held-out ${s.heldOut.toFixed(4)} >= saturation ${saturation} — no headroom, loop must not run`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Run one flywheel generation. Deterministic given the scorer and signer seed.
|
|
40
|
+
* Never mutates fleet state — it returns the verdict + a signed receipt; serving
|
|
41
|
+
* the champion is a separate, reversible step (serveChampion / rollback).
|
|
42
|
+
*/
|
|
43
|
+
export async function runFlywheelGeneration(input) {
|
|
44
|
+
const ruleVersion = input.ruleVersion ?? 'accept/v1';
|
|
45
|
+
const provenanceTier = input.provenanceTier ?? DEFAULT_PROVENANCE_TIER;
|
|
46
|
+
const baselineScores = await input.scorer(input.baseline);
|
|
47
|
+
const candidateScores = await input.scorer(input.candidate);
|
|
48
|
+
const sealed = {
|
|
49
|
+
candidateHeldOut: candidateScores.heldOut,
|
|
50
|
+
baselineHeldOut: baselineScores.heldOut,
|
|
51
|
+
candidateAnchorMean: candidateScores.anchorMean,
|
|
52
|
+
baselineAnchorMean: baselineScores.anchorMean,
|
|
53
|
+
anchorHash: input.anchorHash,
|
|
54
|
+
anchorTol: input.anchorTol,
|
|
55
|
+
provenanceTier,
|
|
56
|
+
allowJudgeTier: input.allowJudgeTier,
|
|
57
|
+
};
|
|
58
|
+
const ruleResult = reExecuteGate(ruleVersion, sealed);
|
|
59
|
+
const verdict = ruleResult.promote ? 'promote' : 'reject';
|
|
60
|
+
const baselinePolicyId = policyId(input.baseline);
|
|
61
|
+
const candidatePolicyId = policyId(input.candidate);
|
|
62
|
+
const receipt = signReceipt({
|
|
63
|
+
generation: input.generation,
|
|
64
|
+
ruleVersion,
|
|
65
|
+
ruleFingerprint: gateFingerprint(ruleVersion),
|
|
66
|
+
sealed,
|
|
67
|
+
sealedHash: sealedHash(sealed),
|
|
68
|
+
verdict,
|
|
69
|
+
baselinePolicyId,
|
|
70
|
+
candidatePolicyId,
|
|
71
|
+
signerKeyId: input.signer.keyId,
|
|
72
|
+
publicKeyPem: input.signer.publicKeyPem,
|
|
73
|
+
}, input.signer);
|
|
74
|
+
return {
|
|
75
|
+
generation: input.generation,
|
|
76
|
+
verdict,
|
|
77
|
+
baselinePolicyId,
|
|
78
|
+
candidatePolicyId,
|
|
79
|
+
scores: { baseline: baselineScores, candidate: candidateScores },
|
|
80
|
+
receipt,
|
|
81
|
+
champion: verdict === 'promote' ? input.candidate : input.baseline,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Reconstruct + validate a lineage from an ordered receipt list (ADR-118 §4).
|
|
86
|
+
* Proves the chain compounds and every step is replayable — the property that
|
|
87
|
+
* makes a stub unable to launder a regression (a forged promote fails
|
|
88
|
+
* verifyPromotion; a broken chain fails lineageIntact).
|
|
89
|
+
*/
|
|
90
|
+
export function reconstructLineage(receipts) {
|
|
91
|
+
let promotions = 0;
|
|
92
|
+
let lineageIntact = true;
|
|
93
|
+
let allReplayable = true;
|
|
94
|
+
let lastPromotedCandidate = null;
|
|
95
|
+
for (const r of receipts) {
|
|
96
|
+
// Replayability: signature + frozen-rule re-execution (ADR-120).
|
|
97
|
+
if (!verifyReceiptSignature(r))
|
|
98
|
+
allReplayable = false;
|
|
99
|
+
const replay = verifyPromotion(toPromotionReceipt(r));
|
|
100
|
+
if (!replay.valid)
|
|
101
|
+
allReplayable = false;
|
|
102
|
+
if (r.verdict === 'promote') {
|
|
103
|
+
// A promoted generation must re-base on the previous promoted champion.
|
|
104
|
+
if (lastPromotedCandidate !== null && r.baselinePolicyId !== lastPromotedCandidate) {
|
|
105
|
+
lineageIntact = false;
|
|
106
|
+
}
|
|
107
|
+
lastPromotedCandidate = r.candidatePolicyId;
|
|
108
|
+
promotions++;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
promotions,
|
|
113
|
+
lineageIntact,
|
|
114
|
+
allReplayable,
|
|
115
|
+
reason: `${promotions} promotion(s); lineage ${lineageIntact ? 'intact' : 'BROKEN'}; `
|
|
116
|
+
+ `${allReplayable ? 'all replayable' : 'NOT all replayable'}`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Initialize the active pointer at the gen-0 root policy. */
|
|
120
|
+
export function initActivePolicy(root) {
|
|
121
|
+
return { current: root, currentId: policyId(root), previous: null, previousId: null, generation: 0 };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Serve a newly-promoted champion, shifting the old current into `previous` as
|
|
125
|
+
* the rollback target (serve-then-shadow: the new policy is served, the old is
|
|
126
|
+
* retained one generation for the canary to fall back to).
|
|
127
|
+
*/
|
|
128
|
+
export function serveChampion(active, champion, generation) {
|
|
129
|
+
return {
|
|
130
|
+
current: champion,
|
|
131
|
+
currentId: policyId(champion),
|
|
132
|
+
previous: active.current,
|
|
133
|
+
previousId: active.currentId,
|
|
134
|
+
generation,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/** Roll the active pointer back to its previous policy (drift-canary auto-rollback). */
|
|
138
|
+
export function rollback(active) {
|
|
139
|
+
if (active.previous === null)
|
|
140
|
+
return active; // nothing to roll back to
|
|
141
|
+
return {
|
|
142
|
+
current: active.previous,
|
|
143
|
+
currentId: active.previousId,
|
|
144
|
+
previous: null,
|
|
145
|
+
previousId: null,
|
|
146
|
+
generation: active.generation,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Drift canary (ADR-118 §5, ruflo `:259-302`): re-score the served champion
|
|
151
|
+
* against its predecessor on a FRESH harvest; if EITHER the held-out or the
|
|
152
|
+
* anchor score drops below the predecessor, the promotion regressed in
|
|
153
|
+
* production and must be rolled back.
|
|
154
|
+
*/
|
|
155
|
+
export function checkDriftCanary(served, predecessor, tol = 0) {
|
|
156
|
+
const heldOutDrift = served.heldOut < predecessor.heldOut - tol;
|
|
157
|
+
const anchorDrift = served.anchorMean < predecessor.anchorMean - tol;
|
|
158
|
+
const drifted = heldOutDrift || anchorDrift;
|
|
159
|
+
return {
|
|
160
|
+
drifted,
|
|
161
|
+
reason: drifted
|
|
162
|
+
? `drift detected: ${heldOutDrift ? `held-out ${served.heldOut.toFixed(4)}<${predecessor.heldOut.toFixed(4)} ` : ''}`
|
|
163
|
+
+ `${anchorDrift ? `anchor ${served.anchorMean.toFixed(4)}<${predecessor.anchorMean.toFixed(4)}` : ''}`.trim()
|
|
164
|
+
: 'served champion holds vs predecessor — no rollback',
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=generation.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieval policy — the hyperparameters the QE-policy flywheel tunes (ADR-118).
|
|
3
|
+
*
|
|
4
|
+
* The flywheel optimizes AQE's hybrid retrieval/selection policy over
|
|
5
|
+
* `qe_patterns` (the ruflo RetrievalConfig shape), one generation at a time,
|
|
6
|
+
* behind the frozen accept() gate. This module defines the policy and the
|
|
7
|
+
* candidate proposal; it does NOT touch the DB or evaluate anything (the scorer
|
|
8
|
+
* is injected in generation.ts).
|
|
9
|
+
*/
|
|
10
|
+
/** The tunable hybrid-retrieval hyperparameters. */
|
|
11
|
+
export interface RetrievalPolicy {
|
|
12
|
+
/** Dense/sparse blend weight [0,1]. */
|
|
13
|
+
alpha: number;
|
|
14
|
+
/** Weight on subject/title token match. */
|
|
15
|
+
subjectWeight: number;
|
|
16
|
+
/** Weight on body/content token match. */
|
|
17
|
+
bodyWeight: number;
|
|
18
|
+
/** MMR diversity vs relevance tradeoff [0,1]. */
|
|
19
|
+
mmrLambda: number;
|
|
20
|
+
/** Penalty factor for pattern-type mismatch [0,1]. */
|
|
21
|
+
typePenaltyFactor: number;
|
|
22
|
+
}
|
|
23
|
+
/** ADR-082 defaults — the gen-0 root policy. */
|
|
24
|
+
export declare const DEFAULT_POLICY: RetrievalPolicy;
|
|
25
|
+
/**
|
|
26
|
+
* Stable id of a policy — canonical (sorted-key, fixed-precision) hash. Two
|
|
27
|
+
* numerically-equal policies get the same id, so lineage links are exact.
|
|
28
|
+
*/
|
|
29
|
+
export declare function policyId(p: RetrievalPolicy): string;
|
|
30
|
+
/**
|
|
31
|
+
* Propose candidate policies around a baseline — a coarse ±step grid, one axis
|
|
32
|
+
* moved at a time (plus a floor of exploration on every axis). Later generations
|
|
33
|
+
* can bias this toward historically-effective axes (ruflo `biasedGrid`), but the
|
|
34
|
+
* gate is what makes any proposal safe, so a simple grid is a fine start.
|
|
35
|
+
*/
|
|
36
|
+
export declare function proposeCandidates(baseline: RetrievalPolicy, step?: number): RetrievalPolicy[];
|
|
37
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieval policy — the hyperparameters the QE-policy flywheel tunes (ADR-118).
|
|
3
|
+
*
|
|
4
|
+
* The flywheel optimizes AQE's hybrid retrieval/selection policy over
|
|
5
|
+
* `qe_patterns` (the ruflo RetrievalConfig shape), one generation at a time,
|
|
6
|
+
* behind the frozen accept() gate. This module defines the policy and the
|
|
7
|
+
* candidate proposal; it does NOT touch the DB or evaluate anything (the scorer
|
|
8
|
+
* is injected in generation.ts).
|
|
9
|
+
*/
|
|
10
|
+
import { createHash } from 'node:crypto';
|
|
11
|
+
/** ADR-082 defaults — the gen-0 root policy. */
|
|
12
|
+
export const DEFAULT_POLICY = {
|
|
13
|
+
alpha: 0.5,
|
|
14
|
+
subjectWeight: 1.0,
|
|
15
|
+
bodyWeight: 1.0,
|
|
16
|
+
mmrLambda: 0.5,
|
|
17
|
+
typePenaltyFactor: 0.1,
|
|
18
|
+
};
|
|
19
|
+
const AXES = ['alpha', 'subjectWeight', 'bodyWeight', 'mmrLambda', 'typePenaltyFactor'];
|
|
20
|
+
/** Clamp helper — keep weights in sane bounds so candidates stay well-formed. */
|
|
21
|
+
function clamp(v, lo, hi) {
|
|
22
|
+
return Math.min(hi, Math.max(lo, v));
|
|
23
|
+
}
|
|
24
|
+
const BOUNDS = {
|
|
25
|
+
alpha: [0, 1],
|
|
26
|
+
subjectWeight: [0, 4],
|
|
27
|
+
bodyWeight: [0, 4],
|
|
28
|
+
mmrLambda: [0, 1],
|
|
29
|
+
typePenaltyFactor: [0, 1],
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Stable id of a policy — canonical (sorted-key, fixed-precision) hash. Two
|
|
33
|
+
* numerically-equal policies get the same id, so lineage links are exact.
|
|
34
|
+
*/
|
|
35
|
+
export function policyId(p) {
|
|
36
|
+
const canon = AXES.map((k) => `${k}:${p[k].toFixed(6)}`).join('|');
|
|
37
|
+
return createHash('sha256').update(canon).digest('hex').slice(0, 16);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Propose candidate policies around a baseline — a coarse ±step grid, one axis
|
|
41
|
+
* moved at a time (plus a floor of exploration on every axis). Later generations
|
|
42
|
+
* can bias this toward historically-effective axes (ruflo `biasedGrid`), but the
|
|
43
|
+
* gate is what makes any proposal safe, so a simple grid is a fine start.
|
|
44
|
+
*/
|
|
45
|
+
export function proposeCandidates(baseline, step = 0.1) {
|
|
46
|
+
const out = [];
|
|
47
|
+
for (const axis of AXES) {
|
|
48
|
+
for (const dir of [-1, 1]) {
|
|
49
|
+
const [lo, hi] = BOUNDS[axis];
|
|
50
|
+
const moved = clamp(baseline[axis] + dir * step, lo, hi);
|
|
51
|
+
if (moved === baseline[axis])
|
|
52
|
+
continue; // no-op at a bound
|
|
53
|
+
out.push({ ...baseline, [axis]: moved });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// de-dup by id (a bound can collapse two moves)
|
|
57
|
+
const seen = new Set();
|
|
58
|
+
return out.filter((p) => {
|
|
59
|
+
const id = policyId(p);
|
|
60
|
+
if (seen.has(id))
|
|
61
|
+
return false;
|
|
62
|
+
seen.add(id);
|
|
63
|
+
return true;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable, append-only persistence for flywheel evolve receipts (ADR-118 §4).
|
|
3
|
+
*
|
|
4
|
+
* The generational lineage is only trustworthy if it survives the process: a
|
|
5
|
+
* third party must be able to reload the receipts and re-verify each one
|
|
6
|
+
* (signature + frozen-gate re-execution) offline. This stores every receipt —
|
|
7
|
+
* promoted OR rejected — in an append-only table in the unified `memory.db`.
|
|
8
|
+
*
|
|
9
|
+
* Data safety (unified-memory rule): CREATE TABLE IF NOT EXISTS is additive;
|
|
10
|
+
* writes are INSERT-only (no UPDATE/DELETE/DROP in this API); the caller opens
|
|
11
|
+
* the DB and is responsible for backups. The `db` handle is injected so tests
|
|
12
|
+
* run against an in-memory database.
|
|
13
|
+
*/
|
|
14
|
+
import type { Database as DatabaseType } from 'better-sqlite3';
|
|
15
|
+
import { type LineageResult } from './generation.js';
|
|
16
|
+
import type { EvolveReceipt } from './receipt.js';
|
|
17
|
+
/** Idempotent, additive migration — creates the receipts table if absent. */
|
|
18
|
+
export declare function ensureReceiptTable(db: DatabaseType): void;
|
|
19
|
+
/** Append one receipt (INSERT-only). Returns its assigned seq. */
|
|
20
|
+
export declare function persistReceipt(db: DatabaseType, receipt: EvolveReceipt): number;
|
|
21
|
+
/** Append many receipts in one transaction (still INSERT-only). */
|
|
22
|
+
export declare function persistReceipts(db: DatabaseType, receipts: EvolveReceipt[]): number;
|
|
23
|
+
/** Load persisted receipts back into EvolveReceipt objects, ordered by seq. */
|
|
24
|
+
export declare function loadReceipts(db: DatabaseType): EvolveReceipt[];
|
|
25
|
+
/**
|
|
26
|
+
* Reload the persisted lineage and re-verify it end-to-end (signatures +
|
|
27
|
+
* frozen-gate re-execution + compounding chain). This is the offline
|
|
28
|
+
* "trust the re-run, not the log" check applied to what's actually on disk.
|
|
29
|
+
*/
|
|
30
|
+
export declare function verifyPersistedLineage(db: DatabaseType): LineageResult;
|
|
31
|
+
//# sourceMappingURL=receipt-store.d.ts.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable, append-only persistence for flywheel evolve receipts (ADR-118 §4).
|
|
3
|
+
*
|
|
4
|
+
* The generational lineage is only trustworthy if it survives the process: a
|
|
5
|
+
* third party must be able to reload the receipts and re-verify each one
|
|
6
|
+
* (signature + frozen-gate re-execution) offline. This stores every receipt —
|
|
7
|
+
* promoted OR rejected — in an append-only table in the unified `memory.db`.
|
|
8
|
+
*
|
|
9
|
+
* Data safety (unified-memory rule): CREATE TABLE IF NOT EXISTS is additive;
|
|
10
|
+
* writes are INSERT-only (no UPDATE/DELETE/DROP in this API); the caller opens
|
|
11
|
+
* the DB and is responsible for backups. The `db` handle is injected so tests
|
|
12
|
+
* run against an in-memory database.
|
|
13
|
+
*/
|
|
14
|
+
import { reconstructLineage } from './generation.js';
|
|
15
|
+
/** Idempotent, additive migration — creates the receipts table if absent. */
|
|
16
|
+
export function ensureReceiptTable(db) {
|
|
17
|
+
db.exec(`
|
|
18
|
+
CREATE TABLE IF NOT EXISTS flywheel_receipts (
|
|
19
|
+
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
20
|
+
generation INTEGER NOT NULL,
|
|
21
|
+
rule_version TEXT NOT NULL,
|
|
22
|
+
rule_fingerprint TEXT NOT NULL,
|
|
23
|
+
sealed_hash TEXT NOT NULL,
|
|
24
|
+
sealed_json TEXT NOT NULL,
|
|
25
|
+
verdict TEXT NOT NULL,
|
|
26
|
+
baseline_policy_id TEXT NOT NULL,
|
|
27
|
+
candidate_policy_id TEXT NOT NULL,
|
|
28
|
+
signer_key_id TEXT NOT NULL,
|
|
29
|
+
public_key_pem TEXT NOT NULL,
|
|
30
|
+
signature TEXT NOT NULL,
|
|
31
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
32
|
+
)
|
|
33
|
+
`);
|
|
34
|
+
}
|
|
35
|
+
/** Append one receipt (INSERT-only). Returns its assigned seq. */
|
|
36
|
+
export function persistReceipt(db, receipt) {
|
|
37
|
+
ensureReceiptTable(db);
|
|
38
|
+
const info = db.prepare(`
|
|
39
|
+
INSERT INTO flywheel_receipts
|
|
40
|
+
(generation, rule_version, rule_fingerprint, sealed_hash, sealed_json,
|
|
41
|
+
verdict, baseline_policy_id, candidate_policy_id, signer_key_id,
|
|
42
|
+
public_key_pem, signature)
|
|
43
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
44
|
+
`).run(receipt.generation, receipt.ruleVersion, receipt.ruleFingerprint, receipt.sealedHash, JSON.stringify(receipt.sealed), receipt.verdict, receipt.baselinePolicyId, receipt.candidatePolicyId, receipt.signerKeyId, receipt.publicKeyPem, receipt.signature);
|
|
45
|
+
return Number(info.lastInsertRowid);
|
|
46
|
+
}
|
|
47
|
+
/** Append many receipts in one transaction (still INSERT-only). */
|
|
48
|
+
export function persistReceipts(db, receipts) {
|
|
49
|
+
ensureReceiptTable(db);
|
|
50
|
+
const tx = db.transaction((rs) => {
|
|
51
|
+
for (const r of rs)
|
|
52
|
+
persistReceipt(db, r);
|
|
53
|
+
});
|
|
54
|
+
tx(receipts);
|
|
55
|
+
return receipts.length;
|
|
56
|
+
}
|
|
57
|
+
/** Load persisted receipts back into EvolveReceipt objects, ordered by seq. */
|
|
58
|
+
export function loadReceipts(db) {
|
|
59
|
+
ensureReceiptTable(db);
|
|
60
|
+
const rows = db.prepare(`
|
|
61
|
+
SELECT generation, rule_version, rule_fingerprint, sealed_hash, sealed_json,
|
|
62
|
+
verdict, baseline_policy_id, candidate_policy_id, signer_key_id,
|
|
63
|
+
public_key_pem, signature
|
|
64
|
+
FROM flywheel_receipts
|
|
65
|
+
ORDER BY seq ASC
|
|
66
|
+
`).all();
|
|
67
|
+
return rows.map((r) => ({
|
|
68
|
+
generation: r.generation,
|
|
69
|
+
ruleVersion: r.rule_version,
|
|
70
|
+
ruleFingerprint: r.rule_fingerprint,
|
|
71
|
+
sealed: JSON.parse(r.sealed_json),
|
|
72
|
+
sealedHash: r.sealed_hash,
|
|
73
|
+
verdict: r.verdict === 'promote' ? 'promote' : 'reject',
|
|
74
|
+
baselinePolicyId: r.baseline_policy_id,
|
|
75
|
+
candidatePolicyId: r.candidate_policy_id,
|
|
76
|
+
signerKeyId: r.signer_key_id,
|
|
77
|
+
publicKeyPem: r.public_key_pem,
|
|
78
|
+
signature: r.signature,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Reload the persisted lineage and re-verify it end-to-end (signatures +
|
|
83
|
+
* frozen-gate re-execution + compounding chain). This is the offline
|
|
84
|
+
* "trust the re-run, not the log" check applied to what's actually on disk.
|
|
85
|
+
*/
|
|
86
|
+
export function verifyPersistedLineage(db) {
|
|
87
|
+
return reconstructLineage(loadReceipts(db));
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=receipt-store.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519-signed evolve receipts for the QE-policy flywheel (ADR-118 §4).
|
|
3
|
+
*
|
|
4
|
+
* Every generation — promoted OR rejected — emits a signed receipt into an
|
|
5
|
+
* append-only lineage. A receipt seals the decision inputs (composing ADR-116 /
|
|
6
|
+
* ADR-120) and signs the whole body, so a third party can (a) re-execute the
|
|
7
|
+
* frozen rule on the sealed inputs (ADR-120 verifyPromotion) and (b) verify the
|
|
8
|
+
* signature — trusting the SIGNATURE and the RE-RUN, not the producer.
|
|
9
|
+
*
|
|
10
|
+
* Ed25519 via Node's built-in crypto — dependency-free (ADR-118 §6).
|
|
11
|
+
*/
|
|
12
|
+
import type { SealedInputs, PromotionReceipt } from '../../validation/gate-reexecute.js';
|
|
13
|
+
export interface Signer {
|
|
14
|
+
/** Stable id for the signing key (hash of the public key). */
|
|
15
|
+
keyId: string;
|
|
16
|
+
/** SPKI PEM of the public key — travels in the receipt for verification. */
|
|
17
|
+
publicKeyPem: string;
|
|
18
|
+
/** Sign a message, returning a hex signature. */
|
|
19
|
+
sign(message: string): string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create an Ed25519 signer. With a 32-byte seed (hex or Buffer) the keypair is
|
|
23
|
+
* DETERMINISTIC — same seed ⇒ same key ⇒ reproducible receipts (useful for
|
|
24
|
+
* replay bundles and tests). Without a seed, a fresh random keypair is used.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createSigner(seed?: string | Buffer): Signer;
|
|
27
|
+
/** Verify an Ed25519 signature against a public key PEM. Never throws. */
|
|
28
|
+
export declare function verifySignature(publicKeyPem: string, message: string, signatureHex: string): boolean;
|
|
29
|
+
/** A signed evolve receipt — the durable, verifiable record of one generation. */
|
|
30
|
+
export interface EvolveReceipt {
|
|
31
|
+
generation: number;
|
|
32
|
+
/** Frozen acceptance rule this decision used (ADR-120). */
|
|
33
|
+
ruleVersion: string;
|
|
34
|
+
ruleFingerprint: string;
|
|
35
|
+
/** Sealed decision inputs + their content hash (ADR-116/120). */
|
|
36
|
+
sealed: SealedInputs;
|
|
37
|
+
sealedHash: string;
|
|
38
|
+
/** The verdict this generation recorded. */
|
|
39
|
+
verdict: 'promote' | 'reject';
|
|
40
|
+
/** Lineage links: which policy was the baseline, which the candidate. */
|
|
41
|
+
baselinePolicyId: string;
|
|
42
|
+
candidatePolicyId: string;
|
|
43
|
+
/** Signer identity + public key (for offline verification). */
|
|
44
|
+
signerKeyId: string;
|
|
45
|
+
publicKeyPem: string;
|
|
46
|
+
/** Ed25519 signature over the canonical receipt body. */
|
|
47
|
+
signature: string;
|
|
48
|
+
}
|
|
49
|
+
/** The signed portion of a receipt (everything except the signature itself). */
|
|
50
|
+
export type ReceiptBody = Omit<EvolveReceipt, 'signature'>;
|
|
51
|
+
/** Canonical serialization of the receipt body for signing/verifying. */
|
|
52
|
+
export declare function receiptBodyString(body: ReceiptBody): string;
|
|
53
|
+
/** Sign a receipt body, producing a complete signed receipt. */
|
|
54
|
+
export declare function signReceipt(body: ReceiptBody, signer: Signer): EvolveReceipt;
|
|
55
|
+
/** Verify a receipt's Ed25519 signature (does NOT re-execute the gate — see ADR-120). */
|
|
56
|
+
export declare function verifyReceiptSignature(receipt: EvolveReceipt): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Adapt an EvolveReceipt to the ADR-120 PromotionReceipt shape so it can be
|
|
59
|
+
* re-verified by `verifyPromotion` (maps `verdict` → `recordedVerdict`).
|
|
60
|
+
*/
|
|
61
|
+
export declare function toPromotionReceipt(receipt: EvolveReceipt): PromotionReceipt;
|
|
62
|
+
//# sourceMappingURL=receipt.d.ts.map
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519-signed evolve receipts for the QE-policy flywheel (ADR-118 §4).
|
|
3
|
+
*
|
|
4
|
+
* Every generation — promoted OR rejected — emits a signed receipt into an
|
|
5
|
+
* append-only lineage. A receipt seals the decision inputs (composing ADR-116 /
|
|
6
|
+
* ADR-120) and signs the whole body, so a third party can (a) re-execute the
|
|
7
|
+
* frozen rule on the sealed inputs (ADR-120 verifyPromotion) and (b) verify the
|
|
8
|
+
* signature — trusting the SIGNATURE and the RE-RUN, not the producer.
|
|
9
|
+
*
|
|
10
|
+
* Ed25519 via Node's built-in crypto — dependency-free (ADR-118 §6).
|
|
11
|
+
*/
|
|
12
|
+
import { generateKeyPairSync, createPrivateKey, createPublicKey, sign as edSign, verify as edVerify, createHash, } from 'node:crypto';
|
|
13
|
+
/** Derive a stable key id from a public key PEM. */
|
|
14
|
+
function keyIdOf(publicKeyPem) {
|
|
15
|
+
return createHash('sha256').update(publicKeyPem).digest('hex').slice(0, 16);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create an Ed25519 signer. With a 32-byte seed (hex or Buffer) the keypair is
|
|
19
|
+
* DETERMINISTIC — same seed ⇒ same key ⇒ reproducible receipts (useful for
|
|
20
|
+
* replay bundles and tests). Without a seed, a fresh random keypair is used.
|
|
21
|
+
*/
|
|
22
|
+
export function createSigner(seed) {
|
|
23
|
+
let privateKey;
|
|
24
|
+
let publicKey;
|
|
25
|
+
if (seed !== undefined) {
|
|
26
|
+
const raw = typeof seed === 'string' ? Buffer.from(seed, 'hex') : seed;
|
|
27
|
+
if (raw.length !== 32) {
|
|
28
|
+
throw new Error(`Ed25519 seed must be 32 bytes (got ${raw.length}).`);
|
|
29
|
+
}
|
|
30
|
+
// PKCS#8 wrapper for a raw Ed25519 seed: fixed 16-byte prefix + 32-byte seed.
|
|
31
|
+
const pkcs8 = Buffer.concat([
|
|
32
|
+
Buffer.from('302e020100300506032b657004220420', 'hex'),
|
|
33
|
+
raw,
|
|
34
|
+
]);
|
|
35
|
+
privateKey = createPrivateKey({ key: pkcs8, format: 'der', type: 'pkcs8' });
|
|
36
|
+
publicKey = createPublicKey(privateKey);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
({ privateKey, publicKey } = generateKeyPairSync('ed25519'));
|
|
40
|
+
}
|
|
41
|
+
const publicKeyPem = publicKey.export({ format: 'pem', type: 'spki' }).toString();
|
|
42
|
+
return {
|
|
43
|
+
keyId: keyIdOf(publicKeyPem),
|
|
44
|
+
publicKeyPem,
|
|
45
|
+
sign(message) {
|
|
46
|
+
return edSign(null, Buffer.from(message, 'utf8'), privateKey).toString('hex');
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Verify an Ed25519 signature against a public key PEM. Never throws. */
|
|
51
|
+
export function verifySignature(publicKeyPem, message, signatureHex) {
|
|
52
|
+
try {
|
|
53
|
+
const publicKey = createPublicKey(publicKeyPem);
|
|
54
|
+
return edVerify(null, Buffer.from(message, 'utf8'), publicKey, Buffer.from(signatureHex, 'hex'));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** Canonical serialization of the receipt body for signing/verifying. */
|
|
61
|
+
export function receiptBodyString(body) {
|
|
62
|
+
// Field order is fixed here (not sorted) so it is explicit and stable.
|
|
63
|
+
return JSON.stringify({
|
|
64
|
+
generation: body.generation,
|
|
65
|
+
ruleVersion: body.ruleVersion,
|
|
66
|
+
ruleFingerprint: body.ruleFingerprint,
|
|
67
|
+
sealedHash: body.sealedHash,
|
|
68
|
+
verdict: body.verdict,
|
|
69
|
+
baselinePolicyId: body.baselinePolicyId,
|
|
70
|
+
candidatePolicyId: body.candidatePolicyId,
|
|
71
|
+
signerKeyId: body.signerKeyId,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** Sign a receipt body, producing a complete signed receipt. */
|
|
75
|
+
export function signReceipt(body, signer) {
|
|
76
|
+
const signature = signer.sign(receiptBodyString(body));
|
|
77
|
+
return { ...body, signature };
|
|
78
|
+
}
|
|
79
|
+
/** Verify a receipt's Ed25519 signature (does NOT re-execute the gate — see ADR-120). */
|
|
80
|
+
export function verifyReceiptSignature(receipt) {
|
|
81
|
+
const { signature, ...body } = receipt;
|
|
82
|
+
return verifySignature(receipt.publicKeyPem, receiptBodyString(body), signature);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Adapt an EvolveReceipt to the ADR-120 PromotionReceipt shape so it can be
|
|
86
|
+
* re-verified by `verifyPromotion` (maps `verdict` → `recordedVerdict`).
|
|
87
|
+
*/
|
|
88
|
+
export function toPromotionReceipt(receipt) {
|
|
89
|
+
return {
|
|
90
|
+
ruleVersion: receipt.ruleVersion,
|
|
91
|
+
ruleFingerprint: receipt.ruleFingerprint,
|
|
92
|
+
sealedHash: receipt.sealedHash,
|
|
93
|
+
sealed: receipt.sealed,
|
|
94
|
+
recordedVerdict: receipt.verdict,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=receipt.js.map
|