@remnic/core 9.3.612 → 9.3.614
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/dist/access-cli.js +58 -57
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +4 -2
- package/dist/access-http.js +22 -22
- package/dist/access-mcp.d.ts +9 -2
- package/dist/access-mcp.js +19 -19
- package/dist/access-schema.d.ts +12 -12
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-D2J9dh_9.d.ts → access-service-DGG_2xPK.d.ts} +1 -1
- package/dist/access-service.d.ts +2 -2
- package/dist/access-service.js +16 -16
- package/dist/active-recall.js +20 -3
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/behavior-learner.js +2 -3
- package/dist/behavior-learner.js.map +1 -1
- package/dist/bootstrap.d.ts +1 -1
- package/dist/briefing.js +3 -3
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +1 -1
- package/dist/calibration.d.ts +5 -2
- package/dist/calibration.js +7 -5
- package/dist/calibration.js.map +1 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/causal-consolidation.d.ts +8 -2
- package/dist/causal-consolidation.js +13 -11
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-3BP57I6J.js → chunk-2F6NP3NT.js} +2 -1
- package/dist/{chunk-3BP57I6J.js.map → chunk-2F6NP3NT.js.map} +1 -1
- package/dist/{chunk-AU7Q3LSC.js → chunk-2QSZNTDO.js} +4 -4
- package/dist/{chunk-HSVJGWYS.js → chunk-2ROPI5OE.js} +2 -2
- package/dist/{chunk-C4SQJZAF.js → chunk-2SGJY2UY.js} +6 -3
- package/dist/chunk-2SGJY2UY.js.map +1 -0
- package/dist/{chunk-ZDTVJXIP.js → chunk-3MAONBX3.js} +13 -5
- package/dist/chunk-3MAONBX3.js.map +1 -0
- package/dist/{chunk-G3Z3QEF5.js → chunk-3PY7VHV7.js} +2 -2
- package/dist/chunk-3PY7VHV7.js.map +1 -0
- package/dist/{chunk-CF3ZF2YU.js → chunk-3QSU4NFF.js} +3 -3
- package/dist/{chunk-AJA46VX5.js → chunk-3T74IZB3.js} +11 -2
- package/dist/chunk-3T74IZB3.js.map +1 -0
- package/dist/{chunk-KVEVLBKC.js → chunk-4HFJQCJZ.js} +13 -8
- package/dist/chunk-4HFJQCJZ.js.map +1 -0
- package/dist/{chunk-KGK2QKWL.js → chunk-4R4KTDIE.js} +1 -1
- package/dist/chunk-4R4KTDIE.js.map +1 -0
- package/dist/{chunk-OI27U2HT.js → chunk-5BTCT236.js} +2 -2
- package/dist/{chunk-CO7ZO4TU.js → chunk-5VDJMYTF.js} +2 -2
- package/dist/{chunk-BFBF3XEF.js → chunk-6BDVBBBY.js} +33 -25
- package/dist/{chunk-BFBF3XEF.js.map → chunk-6BDVBBBY.js.map} +1 -1
- package/dist/{chunk-EAZGEEG2.js → chunk-6L46YAEZ.js} +45 -9
- package/dist/chunk-6L46YAEZ.js.map +1 -0
- package/dist/{chunk-YFS5OEKO.js → chunk-7MLB4NCL.js} +2 -2
- package/dist/{chunk-IOTENEVL.js → chunk-7YQFWOF7.js} +57 -50
- package/dist/chunk-7YQFWOF7.js.map +1 -0
- package/dist/{chunk-2QANQKSQ.js → chunk-ADNZVFXG.js} +15 -15
- package/dist/{chunk-LZ3VEOU5.js → chunk-AL4RAJL5.js} +22 -5
- package/dist/chunk-AL4RAJL5.js.map +1 -0
- package/dist/{chunk-557IAFPD.js → chunk-APRRL26Q.js} +2 -2
- package/dist/{chunk-QDDHYAKV.js → chunk-AZDOWD2L.js} +2 -2
- package/dist/{chunk-TH67Q46T.js → chunk-B6FDZPCF.js} +17 -9
- package/dist/chunk-B6FDZPCF.js.map +1 -0
- package/dist/{chunk-MLT75J5S.js → chunk-B6SU7YSE.js} +3 -3
- package/dist/{chunk-FXKPZ3H6.js → chunk-BPSGLMQ4.js} +2 -2
- package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-NOMEVTUD.js → chunk-C6C7XVKG.js} +5 -4
- package/dist/chunk-C6C7XVKG.js.map +1 -0
- package/dist/{chunk-XKIQZXUB.js → chunk-CI7RKSRE.js} +7 -1
- package/dist/chunk-CI7RKSRE.js.map +1 -0
- package/dist/{chunk-IK34DVAC.js → chunk-CIOMS6DI.js} +2 -2
- package/dist/{chunk-2I5JGH3M.js → chunk-CYEPCZN5.js} +2 -2
- package/dist/{chunk-2I5JGH3M.js.map → chunk-CYEPCZN5.js.map} +1 -1
- package/dist/{chunk-JHMFYY7L.js → chunk-DCGT4FPP.js} +13 -5
- package/dist/chunk-DCGT4FPP.js.map +1 -0
- package/dist/{chunk-7DZRO2DC.js → chunk-DEPRLVLK.js} +2 -2
- package/dist/{chunk-CSKLPDN6.js → chunk-DEVUWMME.js} +52 -19
- package/dist/chunk-DEVUWMME.js.map +1 -0
- package/dist/{chunk-DHGSZ3UD.js → chunk-DGNQRNLL.js} +2 -2
- package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/chunk-FAV25DUZ.js +12 -0
- package/dist/chunk-FAV25DUZ.js.map +1 -0
- package/dist/{chunk-ETUPBUHB.js → chunk-GDASG7NC.js} +2 -2
- package/dist/{chunk-L227SKTB.js → chunk-GDB4J2H3.js} +17 -1
- package/dist/chunk-GDB4J2H3.js.map +1 -0
- package/dist/{chunk-IP73YCZP.js → chunk-GLPBYIXN.js} +4 -2
- package/dist/chunk-GLPBYIXN.js.map +1 -0
- package/dist/{chunk-4HP7HIE3.js → chunk-HP5FMB6L.js} +2 -2
- package/dist/{chunk-EVZFIAPG.js → chunk-IBTZEBUD.js} +23 -10
- package/dist/chunk-IBTZEBUD.js.map +1 -0
- package/dist/{chunk-DOX2CG6Y.js → chunk-IEUU7O4F.js} +2 -2
- package/dist/{chunk-JNANKJLN.js → chunk-JOASJWQR.js} +2 -2
- package/dist/chunk-JOASJWQR.js.map +1 -0
- package/dist/{chunk-WSGF57U2.js → chunk-JQDZQ4TB.js} +2 -2
- package/dist/{chunk-HINSGUA7.js → chunk-KBL3JJR6.js} +9 -13
- package/dist/chunk-KBL3JJR6.js.map +1 -0
- package/dist/{chunk-W7L6HXUC.js → chunk-LXOM6IQU.js} +2 -2
- package/dist/{chunk-G6R5UD3Q.js → chunk-MGN7VHWQ.js} +42 -1
- package/dist/{chunk-G6R5UD3Q.js.map → chunk-MGN7VHWQ.js.map} +1 -1
- package/dist/{chunk-DLJ4IR6M.js → chunk-MHQC2WU2.js} +2 -2
- package/dist/chunk-MHQC2WU2.js.map +1 -0
- package/dist/{chunk-6JGNHWCI.js → chunk-OBIRVF36.js} +3 -3
- package/dist/{chunk-CHCA44C3.js → chunk-ODPLEWB6.js} +3 -3
- package/dist/chunk-ODPLEWB6.js.map +1 -0
- package/dist/{chunk-HENLZHIT.js → chunk-OIF36KGD.js} +7 -4
- package/dist/chunk-OIF36KGD.js.map +1 -0
- package/dist/{chunk-GUPISBV2.js → chunk-PP2JH3GP.js} +2 -2
- package/dist/{chunk-OXJBNGBK.js → chunk-PSUB67YB.js} +2 -2
- package/dist/{chunk-UWY7GIVS.js → chunk-PYIFUBRK.js} +45 -13
- package/dist/chunk-PYIFUBRK.js.map +1 -0
- package/dist/{chunk-KIB7SDIJ.js → chunk-Q6YIJGXJ.js} +2 -2
- package/dist/{chunk-PPPZY2EU.js → chunk-QEMCQFDW.js} +2 -2
- package/dist/{chunk-ZT3EGNLR.js → chunk-QPD426WT.js} +2 -2
- package/dist/{chunk-RLV3PQGH.js → chunk-QVO4YOB7.js} +6 -6
- package/dist/{chunk-GMAG2HS4.js → chunk-RG3LBSGH.js} +46 -9
- package/dist/chunk-RG3LBSGH.js.map +1 -0
- package/dist/{chunk-XSWKORGM.js → chunk-S53OYO3F.js} +3 -1
- package/dist/chunk-S53OYO3F.js.map +1 -0
- package/dist/{chunk-YCN4BVDK.js → chunk-SCPFRKIT.js} +4 -2
- package/dist/chunk-SCPFRKIT.js.map +1 -0
- package/dist/{chunk-HJNQQICM.js → chunk-T5XWMMU2.js} +107 -50
- package/dist/chunk-T5XWMMU2.js.map +1 -0
- package/dist/{chunk-NZPF2SYV.js → chunk-T7N6KQGS.js} +138 -5
- package/dist/chunk-T7N6KQGS.js.map +1 -0
- package/dist/{chunk-VJXSUAO7.js → chunk-TNOWU6RP.js} +13 -10
- package/dist/chunk-TNOWU6RP.js.map +1 -0
- package/dist/{chunk-PCI747N2.js → chunk-TZVQQTG4.js} +48 -19
- package/dist/chunk-TZVQQTG4.js.map +1 -0
- package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-IK7DCC5H.js → chunk-VMGLYN42.js} +2 -2
- package/dist/{chunk-5RPTH6AU.js → chunk-VPGUMLBA.js} +8 -7
- package/dist/chunk-VPGUMLBA.js.map +1 -0
- package/dist/{chunk-KM2A35EO.js → chunk-WB3LYXC5.js} +11 -7
- package/dist/chunk-WB3LYXC5.js.map +1 -0
- package/dist/{chunk-NSKYFGDL.js → chunk-X4QQB7O6.js} +2 -2
- package/dist/{chunk-HPWVAEET.js → chunk-X6IRLNOO.js} +3 -7
- package/dist/chunk-X6IRLNOO.js.map +1 -0
- package/dist/{chunk-46GJIW5M.js → chunk-XAZOWLW4.js} +5 -5
- package/dist/{chunk-46GJIW5M.js.map → chunk-XAZOWLW4.js.map} +1 -1
- package/dist/{chunk-XPSVGJYA.js → chunk-YRMKDTKF.js} +12 -9
- package/dist/chunk-YRMKDTKF.js.map +1 -0
- package/dist/{chunk-6ZZP4EJF.js → chunk-ZJR7VG5L.js} +3 -3
- package/dist/{chunk-6ZZP4EJF.js.map → chunk-ZJR7VG5L.js.map} +1 -1
- package/dist/{cli-OrfKXNU4.d.ts → cli-DWeu7eTY.d.ts} +6 -2
- package/dist/cli.d.ts +3 -3
- package/dist/cli.js +60 -59
- package/dist/compounding/engine.js +3 -3
- package/dist/compounding/preference-consolidator.js +39 -11
- package/dist/compounding/preference-consolidator.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/index.js +3 -3
- package/dist/consolidation-provenance-check.js +1 -1
- package/dist/contradiction/index.js +4 -4
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/indexer.js +1 -1
- package/dist/cross-namespace-budget.js +1 -1
- package/dist/enrichment/index.js +1 -1
- package/dist/entity-retrieval.js +3 -3
- package/dist/evals.js +1 -1
- package/dist/explicit-capture.d.ts +1 -1
- package/dist/extraction-judge.js +8 -1
- package/dist/extraction.js +2 -2
- package/dist/fallback-llm.d.ts +23 -6
- package/dist/fallback-llm.js +5 -3
- package/dist/{first-start-migration-GYJWIH36.js → first-start-migration-FF7YFGRP.js} +6 -6
- package/dist/index.d.ts +3 -3
- package/dist/index.js +94 -93
- package/dist/index.js.map +1 -1
- package/dist/lcm/archive.js +2 -2
- package/dist/lcm/engine.js +5 -5
- package/dist/lcm/index.js +7 -7
- package/dist/lcm/summarizer.js +3 -3
- package/dist/maintenance/memory-governance-cron.d.ts +6 -4
- package/dist/maintenance/memory-governance-cron.js +1 -1
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/mcp-memory-inspector-app.d.ts +2 -2
- package/dist/mcp-memory-inspector-app.js +1 -1
- package/dist/migrate/from-engram.js +1 -1
- package/dist/namespaces/migrate.js +16 -15
- package/dist/namespaces/search.js +12 -11
- package/dist/namespaces/storage.js +3 -3
- package/dist/network/webdav.d.ts +2 -0
- package/dist/network/webdav.js +1 -1
- package/dist/objective-state-writers.js +2 -2
- package/dist/operator-toolkit.d.ts +3 -1
- package/dist/operator-toolkit.js +21 -20
- package/dist/{orchestrator-DTRQG75J.d.ts → orchestrator-CqWOjfgl.d.ts} +46 -3
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.js +47 -44
- package/dist/patterns-cli.js +1 -1
- package/dist/qmd-recall-cache.d.ts +2 -0
- package/dist/qmd-recall-cache.js +1 -1
- package/dist/qmd.d.ts +37 -2
- package/dist/qmd.js +4 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-planner-llm.d.ts +57 -0
- package/dist/recall-planner-llm.js +167 -0
- package/dist/recall-planner-llm.js.map +1 -0
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.js +2 -2
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.js +2 -2
- package/dist/routing/store.js +1 -1
- package/dist/search/factory.js +11 -10
- package/dist/search/index.js +11 -10
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +3 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +3 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/noop-backend.js +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +3 -2
- package/dist/search/port.d.ts +6 -1
- package/dist/search/port.js +7 -0
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/search/remote-backend.js +1 -1
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/session-observer-state.js +1 -1
- package/dist/storage.js +2 -2
- package/dist/summarizer.js +2 -2
- package/dist/temporal-index.js +1 -1
- package/dist/{tier-stats-SKML2OSF.js → tier-stats-3LYQ3VV5.js} +3 -3
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/export-sqlite.js +1 -1
- package/dist/types.d.ts +32 -0
- package/dist/types.js +1 -1
- package/dist/utility-learner.js +1 -1
- package/dist/utility-runtime.js +2 -2
- package/dist/verified-recall.js +3 -3
- package/dist/work/board.js +2 -2
- package/dist/work/storage.d.ts +2 -0
- package/dist/work/storage.js +1 -1
- package/package.json +1 -1
- package/src/access-http.ts +3 -0
- package/src/access-mcp.test.ts +51 -0
- package/src/access-mcp.ts +26 -5
- package/src/active-recall.test.ts +40 -0
- package/src/active-recall.ts +19 -2
- package/src/behavior-learner.ts +5 -3
- package/src/buffer-session.test.ts +58 -0
- package/src/buffer-surprise-trigger.test.ts +4 -18
- package/src/buffer.ts +39 -11
- package/src/calibration.ts +10 -4
- package/src/causal-consolidation.test.ts +47 -2
- package/src/causal-consolidation.ts +13 -9
- package/src/cli.ts +19 -4
- package/src/compounding/engine.ts +2 -0
- package/src/compounding/preference-consolidator.test.ts +292 -0
- package/src/compounding/preference-consolidator.ts +55 -19
- package/src/config.test.ts +213 -0
- package/src/config.ts +175 -4
- package/src/connectors/codex-materialize-runner.ts +7 -4
- package/src/consolidation-provenance-check.ts +24 -5
- package/src/conversation-index/indexer.test.ts +22 -0
- package/src/conversation-index/indexer.ts +7 -3
- package/src/cross-namespace-budget.test.ts +44 -21
- package/src/cross-namespace-budget.ts +2 -2
- package/src/enrichment/pipeline.ts +11 -16
- package/src/evals.ts +1 -1
- package/src/extraction-judge-chain.test.ts +55 -0
- package/src/extraction-judge.ts +7 -9
- package/src/extraction.ts +16 -5
- package/src/fallback-llm.test.ts +600 -1
- package/src/fallback-llm.ts +91 -22
- package/src/maintenance/memory-governance-cron.ts +39 -29
- package/src/mcp-memory-inspector-app.ts +54 -12
- package/src/message-parts/index.ts +6 -0
- package/src/message-parts/message-parts.test.ts +30 -0
- package/src/migrate/from-engram.ts +19 -5
- package/src/namespaces/search.test.ts +15 -2
- package/src/namespaces/search.ts +1 -1
- package/src/network/webdav.ts +61 -21
- package/src/operator-toolkit.ts +6 -2
- package/src/orchestrator.ts +173 -20
- package/src/qmd-client.test.ts +85 -0
- package/src/qmd-recall-cache.test.ts +16 -0
- package/src/qmd-recall-cache.ts +7 -0
- package/src/qmd.test.ts +54 -0
- package/src/qmd.ts +119 -19
- package/src/recall-planner-llm.test.ts +224 -0
- package/src/recall-planner-llm.ts +289 -0
- package/src/routing/store.ts +4 -8
- package/src/search/factory.ts +3 -0
- package/src/search/lancedb-backend.ts +15 -3
- package/src/search/meilisearch-backend.ts +70 -7
- package/src/search/noop-backend.ts +5 -1
- package/src/search/orama-backend.ts +15 -3
- package/src/search/port.ts +15 -0
- package/src/search/remote-backend.ts +5 -1
- package/src/session-observer-state.ts +1 -1
- package/src/summarizer.ts +3 -3
- package/src/temporal-index.test.ts +18 -0
- package/src/temporal-index.ts +45 -0
- package/src/training-export/cli-date-validation.test.ts +36 -0
- package/src/training-export/date-parse.ts +21 -2
- package/src/transfer/export-sqlite.ts +3 -0
- package/src/types.ts +35 -0
- package/src/utility-learner.ts +1 -0
- package/src/work/storage.ts +23 -0
- package/dist/chunk-5RPTH6AU.js.map +0 -1
- package/dist/chunk-AJA46VX5.js.map +0 -1
- package/dist/chunk-C4SQJZAF.js.map +0 -1
- package/dist/chunk-CHCA44C3.js.map +0 -1
- package/dist/chunk-CSKLPDN6.js.map +0 -1
- package/dist/chunk-DLJ4IR6M.js.map +0 -1
- package/dist/chunk-EAZGEEG2.js.map +0 -1
- package/dist/chunk-EVZFIAPG.js.map +0 -1
- package/dist/chunk-G3Z3QEF5.js.map +0 -1
- package/dist/chunk-GMAG2HS4.js.map +0 -1
- package/dist/chunk-HENLZHIT.js.map +0 -1
- package/dist/chunk-HINSGUA7.js.map +0 -1
- package/dist/chunk-HJNQQICM.js.map +0 -1
- package/dist/chunk-HPWVAEET.js.map +0 -1
- package/dist/chunk-IOTENEVL.js.map +0 -1
- package/dist/chunk-IP73YCZP.js.map +0 -1
- package/dist/chunk-JHMFYY7L.js.map +0 -1
- package/dist/chunk-JNANKJLN.js.map +0 -1
- package/dist/chunk-KGK2QKWL.js.map +0 -1
- package/dist/chunk-KM2A35EO.js.map +0 -1
- package/dist/chunk-KVEVLBKC.js.map +0 -1
- package/dist/chunk-L227SKTB.js.map +0 -1
- package/dist/chunk-LZ3VEOU5.js.map +0 -1
- package/dist/chunk-NOMEVTUD.js.map +0 -1
- package/dist/chunk-NZPF2SYV.js.map +0 -1
- package/dist/chunk-PCI747N2.js.map +0 -1
- package/dist/chunk-TH67Q46T.js.map +0 -1
- package/dist/chunk-UWY7GIVS.js.map +0 -1
- package/dist/chunk-VJXSUAO7.js.map +0 -1
- package/dist/chunk-XKIQZXUB.js.map +0 -1
- package/dist/chunk-XPSVGJYA.js.map +0 -1
- package/dist/chunk-XSWKORGM.js.map +0 -1
- package/dist/chunk-YCN4BVDK.js.map +0 -1
- package/dist/chunk-ZDTVJXIP.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
- /package/dist/{chunk-AU7Q3LSC.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-HSVJGWYS.js.map → chunk-2ROPI5OE.js.map} +0 -0
- /package/dist/{chunk-CF3ZF2YU.js.map → chunk-3QSU4NFF.js.map} +0 -0
- /package/dist/{chunk-OI27U2HT.js.map → chunk-5BTCT236.js.map} +0 -0
- /package/dist/{chunk-CO7ZO4TU.js.map → chunk-5VDJMYTF.js.map} +0 -0
- /package/dist/{chunk-YFS5OEKO.js.map → chunk-7MLB4NCL.js.map} +0 -0
- /package/dist/{chunk-2QANQKSQ.js.map → chunk-ADNZVFXG.js.map} +0 -0
- /package/dist/{chunk-557IAFPD.js.map → chunk-APRRL26Q.js.map} +0 -0
- /package/dist/{chunk-QDDHYAKV.js.map → chunk-AZDOWD2L.js.map} +0 -0
- /package/dist/{chunk-MLT75J5S.js.map → chunk-B6SU7YSE.js.map} +0 -0
- /package/dist/{chunk-FXKPZ3H6.js.map → chunk-BPSGLMQ4.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-IK34DVAC.js.map → chunk-CIOMS6DI.js.map} +0 -0
- /package/dist/{chunk-7DZRO2DC.js.map → chunk-DEPRLVLK.js.map} +0 -0
- /package/dist/{chunk-DHGSZ3UD.js.map → chunk-DGNQRNLL.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-ETUPBUHB.js.map → chunk-GDASG7NC.js.map} +0 -0
- /package/dist/{chunk-4HP7HIE3.js.map → chunk-HP5FMB6L.js.map} +0 -0
- /package/dist/{chunk-DOX2CG6Y.js.map → chunk-IEUU7O4F.js.map} +0 -0
- /package/dist/{chunk-WSGF57U2.js.map → chunk-JQDZQ4TB.js.map} +0 -0
- /package/dist/{chunk-W7L6HXUC.js.map → chunk-LXOM6IQU.js.map} +0 -0
- /package/dist/{chunk-6JGNHWCI.js.map → chunk-OBIRVF36.js.map} +0 -0
- /package/dist/{chunk-GUPISBV2.js.map → chunk-PP2JH3GP.js.map} +0 -0
- /package/dist/{chunk-OXJBNGBK.js.map → chunk-PSUB67YB.js.map} +0 -0
- /package/dist/{chunk-KIB7SDIJ.js.map → chunk-Q6YIJGXJ.js.map} +0 -0
- /package/dist/{chunk-PPPZY2EU.js.map → chunk-QEMCQFDW.js.map} +0 -0
- /package/dist/{chunk-ZT3EGNLR.js.map → chunk-QPD426WT.js.map} +0 -0
- /package/dist/{chunk-RLV3PQGH.js.map → chunk-QVO4YOB7.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-IK7DCC5H.js.map → chunk-VMGLYN42.js.map} +0 -0
- /package/dist/{chunk-NSKYFGDL.js.map → chunk-X4QQB7O6.js.map} +0 -0
- /package/dist/{first-start-migration-GYJWIH36.js.map → first-start-migration-FF7YFGRP.js.map} +0 -0
- /package/dist/{tier-stats-SKML2OSF.js.map → tier-stats-3LYQ3VV5.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/search/lancedb-backend.ts"],"sourcesContent":["import { log } from \"../logger.js\";\nimport {\n resolveEnsureCollectionArgs,\n type SearchBackend,\n type SearchExecutionOptions,\n type SearchQueryOptions,\n type SearchResult,\n} from \"./port.js\";\nimport type { EmbedHelper, EmbedProviderIdentity, EmbedWithProviderResult } from \"./embed-helper.js\";\nimport { scanMemoryDir } from \"./document-scanner.js\";\nimport { isSearchAborted, throwIfSearchAborted } from \"./abort.js\";\n\nexport interface LanceDbBackendOptions {\n dbPath: string;\n collection: string;\n embedHelper: EmbedHelper;\n memoryDir: string;\n embeddingDimension: number;\n}\n\n/**\n * LanceDB search backend — embedded hybrid FTS+vector with RRF reranking.\n *\n * Uses @lancedb/lancedb for native Arrow-backed storage.\n * One table per collection. Supports full-text, vector, and hybrid search.\n */\nexport class LanceDbBackend implements SearchBackend {\n private readonly dbPath: string;\n private readonly collection: string;\n private readonly embedHelper: EmbedHelper;\n private readonly memoryDir: string;\n private readonly embeddingDimension: number;\n private available = false;\n private db: any = null;\n private lanceModule: any = null;\n private readonly vectorProviderCompatibility = new WeakMap<\n object,\n { providerIdentity: EmbedProviderIdentity; compatible: boolean }\n >();\n\n constructor(opts: LanceDbBackendOptions) {\n this.dbPath = opts.dbPath;\n this.collection = opts.collection;\n this.embedHelper = opts.embedHelper;\n this.memoryDir = opts.memoryDir;\n this.embeddingDimension = opts.embeddingDimension;\n }\n\n async probe(): Promise<boolean> {\n try {\n await this.ensureDb();\n this.available = true;\n return true;\n } catch (err) {\n log.debug(`LanceDbBackend probe failed: ${err}`);\n this.available = false;\n return false;\n }\n }\n\n isAvailable(): boolean {\n return this.available;\n }\n\n debugStatus(): string {\n return `backend=lancedb available=${this.available} dbPath=${this.dbPath}`;\n }\n\n async search(\n query: string,\n _collection?: string,\n maxResults?: number,\n _options?: SearchQueryOptions,\n execution?: SearchExecutionOptions,\n ): Promise<SearchResult[]> {\n return this.hybridSearch(query, _collection, maxResults, execution);\n }\n\n async searchGlobal(query: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n const limit = maxResults ?? 10;\n if (!this.available) return [];\n\n try {\n throwIfSearchAborted(execution, \"LanceDbBackend global search aborted\");\n const db = await this.ensureDb();\n const tableNames = await db.tableNames();\n const allResults: SearchResult[] = [];\n\n for (const name of tableNames) {\n throwIfSearchAborted(execution, \"LanceDbBackend global search aborted\");\n try {\n const table = await db.openTable(name);\n const results = await this.searchTable(table, query, \"hybrid\", limit, execution);\n allResults.push(...results);\n } catch {\n // Skip tables that fail\n }\n }\n\n allResults.sort((a, b) => b.score - a.score);\n return allResults.slice(0, limit);\n } catch (err) {\n log.debug(`LanceDbBackend searchGlobal failed: ${err}`);\n return [];\n }\n }\n\n async bm25Search(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const table = await this.ensureTableForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!table) return [];\n return this.searchTable(table, query, \"fts\", maxResults ?? 10, execution);\n }\n\n async vectorSearch(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const table = await this.ensureTableForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!table) return [];\n return this.searchTable(table, query, \"vector\", maxResults ?? 10, execution);\n }\n\n async hybridSearch(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const table = await this.ensureTableForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!table) return [];\n return this.searchTable(table, query, \"hybrid\", maxResults ?? 10, execution);\n }\n\n async update(execution?: SearchExecutionOptions): Promise<void> {\n await this.updateCollection(this.collection, execution);\n }\n\n async updateCollection(collection: string, execution?: SearchExecutionOptions): Promise<void> {\n await this.updateCollectionFromDir(collection, this.memoryDir, execution);\n }\n\n async updateCollectionFromDir(collection: string, memoryDir: string, execution?: SearchExecutionOptions): Promise<void> {\n if (isSearchAborted(execution)) return;\n let table = await this.ensureTableForCollection(collection);\n if (isSearchAborted(execution)) return;\n if (!table) return;\n\n const docs = await scanMemoryDir(memoryDir);\n if (isSearchAborted(execution)) return;\n if (docs.length === 0) {\n // Clear stale data when no docs remain\n try {\n const db = await this.ensureDb();\n await db.dropTable(collection).catch(() => {});\n if (collection === this.collection) this.table = null;\n } catch {\n // Best-effort cleanup\n }\n return;\n }\n\n const embeddingProviderIdentity = this.embedHelper.getProviderIdentity();\n const existingVectors = new Map<string, {\n vector: number[];\n providerIdentity?: string;\n }>();\n const vectorProviderColumnState = await this.tableVectorProviderColumnState(table);\n if (vectorProviderColumnState === \"missing\") {\n table = await this.recreateTableForCollection(collection);\n if (isSearchAborted(execution)) return;\n if (!table) return;\n } else if (vectorProviderColumnState === \"present\") {\n try {\n const existingRows = await table.query().select([\"docid\", \"vector\", \"vectorProvider\"]).toArray();\n for (const row of existingRows ?? []) {\n if (isSearchAborted(execution)) return;\n const docid = row.docid;\n if (typeof docid !== \"string\") continue;\n const vector = row.vector;\n if (!vector || typeof vector !== \"object\") continue;\n existingVectors.set(docid, {\n vector: Array.from(vector as ArrayLike<number>),\n providerIdentity: typeof row.vectorProvider === \"string\" ? row.vectorProvider : undefined,\n });\n }\n } catch {\n log.debug(\"LanceDbBackend skipped refresh after vector preservation failed\");\n return;\n }\n } else {\n log.debug(\"LanceDbBackend skipped vector preservation after vectorProvider probe failed\");\n return;\n }\n\n const rows = docs.map((d) => {\n const existing = existingVectors.get(d.docid);\n const canPreserveVector =\n existing &&\n this.isCompatibleStoredVector(existing.vector) &&\n (!embeddingProviderIdentity ||\n existing.providerIdentity === embeddingProviderIdentity);\n return {\n docid: d.docid,\n path: d.path,\n content: d.content,\n snippet: d.snippet,\n vector: canPreserveVector\n ? existing.vector\n : new Array(this.embeddingDimension).fill(0),\n vectorProvider: canPreserveVector\n ? existing.providerIdentity ?? \"\"\n : \"\",\n };\n });\n\n try {\n if (isSearchAborted(execution)) return;\n await table.add(rows, { mode: \"overwrite\" });\n this.rememberVectorProviderCompatibility(\n table,\n embeddingProviderIdentity,\n rows.length > 0 && rows.every((row) => row.vectorProvider === embeddingProviderIdentity),\n );\n if (isSearchAborted(execution)) return;\n // Create FTS index on content column\n try {\n await table.createIndex(\"content\", { config: this.lanceIndex.fts() });\n } catch {\n // FTS index creation may fail on some platforms — degrade gracefully\n }\n if (collection === this.collection) this.table = table;\n } catch (err) {\n log.debug(`LanceDbBackend update failed: ${err}`);\n }\n }\n\n async embed(): Promise<void> {\n await this.embedCollection(this.collection);\n }\n\n async embedCollection(collection: string): Promise<void> {\n if (!this.embedHelper.isAvailable()) return;\n\n const table = await this.ensureTableForCollection(collection);\n if (!table) return;\n\n try {\n const embeddingProviderIdentity = this.embedHelper.getProviderIdentity();\n const allRows = await table.query().select([\"docid\", \"content\", \"vector\", \"vectorProvider\"]).toArray();\n const needsEmbed = allRows.filter((row: any) => {\n if (embeddingProviderIdentity && row.vectorProvider !== embeddingProviderIdentity) {\n return true;\n }\n return !this.isCompatibleStoredVector(row.vector);\n });\n\n if (needsEmbed.length === 0) {\n this.rememberVectorProviderCompatibility(table, embeddingProviderIdentity, true);\n return;\n }\n\n let rowsToEmbed = needsEmbed;\n let embedResult = await this.embedHelper.embedBatchWithProvider(\n rowsToEmbed.map((row: any) => row.content as string),\n );\n if (!embedResult) return;\n if (\n embeddingProviderIdentity &&\n embedResult.providerIdentity !== embeddingProviderIdentity\n ) {\n const effectiveProviderIdentity = embedResult.providerIdentity;\n const originalDocids = new Set(rowsToEmbed.map((row: any) => row.docid));\n const effectiveNeedsEmbed = allRows.filter((row: any) => (\n row.vectorProvider !== effectiveProviderIdentity ||\n !this.isCompatibleStoredVector(row.vector)\n ));\n const sameRows =\n effectiveNeedsEmbed.length === rowsToEmbed.length &&\n effectiveNeedsEmbed.every((row: any) => originalDocids.has(row.docid));\n if (!sameRows) {\n const effectiveTexts = effectiveNeedsEmbed.map((row: any) => row.content as string);\n const effectiveEmbedResult = await this.embedHelper.embedBatchWithProvider(effectiveTexts);\n if (effectiveEmbedResult) {\n rowsToEmbed = effectiveNeedsEmbed;\n embedResult = effectiveEmbedResult;\n }\n }\n }\n const { vectors, providerIdentity } = embedResult;\n\n let allEmbedded = true;\n for (let i = 0; i < rowsToEmbed.length; i++) {\n const vec = vectors[i];\n if (!this.isExpectedDimensionVector(vec)) {\n allEmbedded = false;\n continue;\n }\n const docid = rowsToEmbed[i].docid;\n await table.update({\n where: `docid = '${docid.replace(/'/g, \"''\")}'`,\n values: { vector: vec, vectorProvider: providerIdentity },\n });\n }\n if (allEmbedded) {\n this.rememberVectorProviderCompatibility(table, providerIdentity, true);\n } else {\n this.rememberVectorProviderCompatibility(table, providerIdentity, false);\n }\n } catch (err) {\n log.debug(`LanceDbBackend embed failed: ${err}`);\n }\n }\n\n async ensureCollection(\n _memoryDir: string,\n collectionOrExecution?: string | SearchExecutionOptions,\n execution?: SearchExecutionOptions,\n ): Promise<\"present\" | \"missing\" | \"unknown\" | \"skipped\"> {\n const { collection, execution: effectiveExecution } = resolveEnsureCollectionArgs(\n collectionOrExecution,\n execution,\n );\n if (isSearchAborted(effectiveExecution)) return \"skipped\";\n try {\n await this.ensureTableForCollection(collection ?? this.collection);\n return \"present\";\n } catch {\n return \"missing\";\n }\n }\n\n private table: any = null;\n\n private get lanceIndex(): any {\n return this.lanceModule.Index ?? this.lanceModule.default?.Index;\n }\n\n private async ensureDb(): Promise<any> {\n if (this.db) return this.db;\n if (!this.lanceModule) {\n this.lanceModule = await import(\"@lancedb/lancedb\");\n }\n const connect = this.lanceModule.connect ?? this.lanceModule.default?.connect;\n this.db = await connect(this.dbPath);\n return this.db;\n }\n\n private async ensureTableForCollection(collection: string): Promise<any> {\n // For the default collection, use the cached instance\n if (collection === this.collection) return this.ensureTable();\n\n const db = await this.ensureDb();\n const tables = await db.tableNames();\n\n if (tables.includes(collection)) {\n return await db.openTable(collection);\n }\n\n // Create empty table with schema\n const emptyRow = {\n docid: \"__placeholder__\",\n path: \"\",\n content: \"\",\n snippet: \"\",\n vector: new Array(this.embeddingDimension).fill(0),\n vectorProvider: \"\",\n };\n const newTable = await db.createTable(collection, [emptyRow]);\n try {\n await newTable.createIndex(\"content\", { config: this.lanceIndex.fts() });\n } catch {\n // FTS index creation may fail — degrade gracefully\n }\n try {\n await newTable.delete(\"docid = '__placeholder__'\");\n } catch {\n // May fail if delete isn't supported on empty-ish tables\n }\n return newTable;\n }\n\n private async recreateTableForCollection(collection: string): Promise<any> {\n const db = await this.ensureDb();\n try {\n await db.dropTable(collection).catch(() => {});\n } catch {\n // Best-effort legacy schema migration; table creation below may still recover.\n }\n if (collection === this.collection) this.table = null;\n return this.ensureTableForCollection(collection);\n }\n\n private async tableVectorProviderColumnState(table: any): Promise<\"present\" | \"missing\" | \"unknown\"> {\n try {\n await table.query().select([\"vectorProvider\"]).toArray();\n return \"present\";\n } catch (err) {\n if (isMissingVectorProviderColumnError(err)) {\n return \"missing\";\n }\n log.debug(`LanceDbBackend vectorProvider column probe failed: ${err}`);\n return \"unknown\";\n }\n }\n\n private async ensureTable(): Promise<any> {\n if (this.table) return this.table;\n\n const db = await this.ensureDb();\n const tables = await db.tableNames();\n\n if (tables.includes(this.collection)) {\n this.table = await db.openTable(this.collection);\n return this.table;\n }\n\n // Create empty table with schema\n const emptyRow = {\n docid: \"__placeholder__\",\n path: \"\",\n content: \"\",\n snippet: \"\",\n vector: new Array(this.embeddingDimension).fill(0),\n vectorProvider: \"\",\n };\n this.table = await db.createTable(this.collection, [emptyRow]);\n // Create FTS index on content column\n try {\n await this.table.createIndex(\"content\", { config: this.lanceIndex.fts() });\n } catch {\n // FTS index creation may fail — degrade gracefully\n }\n // Remove placeholder row\n try {\n await this.table.delete(\"docid = '__placeholder__'\");\n } catch {\n // May fail if delete isn't supported on empty-ish tables\n }\n return this.table;\n }\n\n private async searchTable(\n table: any,\n query: string,\n mode: \"fts\" | \"vector\" | \"hybrid\",\n limit: number,\n execution?: SearchExecutionOptions,\n ): Promise<SearchResult[]> {\n try {\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n if (mode === \"fts\") {\n const results = await table.search(query, \"fts\").limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n\n if (mode === \"vector\") {\n const embedResult = await this.resolveCompatibleQueryEmbedding(table, query, execution);\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n if (!embedResult) {\n // Fall back to FTS\n const results = await table.search(query, \"fts\").limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n const results = await table.search(embedResult.vector).limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n\n // hybrid — try FTS+vector with RRF reranking\n const embedResult = await this.resolveCompatibleQueryEmbedding(table, query, execution);\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n if (!embedResult) {\n const results = await table.search(query, \"fts\").limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n\n try {\n const results = await table\n .search(query, \"hybrid\")\n .vector(embedResult.vector)\n .limit(limit)\n .toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n } catch {\n // Hybrid may not be supported in all LanceDB versions — fall back to vector\n const results = await table.search(embedResult.vector).limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n } catch (err) {\n log.debug(`LanceDbBackend search (${mode}) failed: ${err}`);\n return [];\n }\n }\n\n private async resolveCompatibleQueryEmbedding(\n table: any,\n query: string,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedWithProviderResult | null> {\n const embedResult = await this.embedHelper.embedWithProvider(query, { signal: execution?.signal });\n throwIfSearchAborted(execution, \"LanceDbBackend query embedding aborted\");\n if (!embedResult || !this.isExpectedDimensionVector(embedResult.vector)) return null;\n\n const storedProviderIdentity = await this.findCompatibleStoredVectorProvider(table, execution);\n if (!storedProviderIdentity) {\n this.rememberVectorProviderCompatibility(table, embedResult.providerIdentity, false);\n return null;\n }\n if (storedProviderIdentity === embedResult.providerIdentity) return embedResult;\n\n const fallbackEmbed = await this.embedQueryWithStoredFallbackProvider(query, storedProviderIdentity, execution);\n throwIfSearchAborted(execution, \"LanceDbBackend fallback query embedding aborted\");\n if (\n fallbackEmbed &&\n fallbackEmbed.providerIdentity === storedProviderIdentity &&\n this.isExpectedDimensionVector(fallbackEmbed.vector)\n ) {\n return fallbackEmbed;\n }\n\n this.rememberVectorProviderCompatibility(table, embedResult.providerIdentity, false);\n return null;\n }\n\n private async embedQueryWithStoredFallbackProvider(\n query: string,\n providerIdentity: EmbedProviderIdentity,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedWithProviderResult | null> {\n const embedWithIdentity = (this.embedHelper as unknown as {\n embedWithFallbackProviderIdentity?: (\n text: string,\n identity: EmbedProviderIdentity,\n options?: { signal?: AbortSignal },\n ) => Promise<EmbedWithProviderResult | null>;\n }).embedWithFallbackProviderIdentity;\n if (typeof embedWithIdentity !== \"function\") return null;\n return embedWithIdentity.call(this.embedHelper, query, providerIdentity, { signal: execution?.signal });\n }\n\n private async findCompatibleStoredVectorProvider(\n table: any,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedProviderIdentity | null> {\n try {\n const cached = this.vectorProviderCompatibility.get(table);\n if (cached?.compatible) return cached.providerIdentity;\n const rows = await table.query().select([\"vector\", \"vectorProvider\"]).toArray();\n let providerIdentity: EmbedProviderIdentity | null = null;\n let compatible = rows.length > 0;\n for (const row of rows ?? []) {\n throwIfSearchAborted(execution, \"LanceDbBackend vector provider check aborted\");\n if (\n typeof row.vectorProvider !== \"string\" ||\n row.vectorProvider.length === 0 ||\n !this.isCompatibleStoredVector(row.vector)\n ) {\n compatible = false;\n break;\n }\n if (providerIdentity && row.vectorProvider !== providerIdentity) {\n compatible = false;\n break;\n }\n providerIdentity = row.vectorProvider as EmbedProviderIdentity;\n }\n if (compatible && providerIdentity) {\n this.vectorProviderCompatibility.set(table, {\n providerIdentity,\n compatible: true,\n });\n return providerIdentity;\n }\n return null;\n } catch (err) {\n if (isSearchAborted(execution)) throw err;\n log.debug(`LanceDbBackend stored vector provider check failed: ${err}`);\n return null;\n }\n }\n\n private mapRows(rows: any[]): SearchResult[] {\n return (rows ?? [])\n .filter((row) => row.docid && row.docid !== \"__placeholder__\")\n .map((row) => ({\n docid: row.docid ?? \"\",\n path: row.path ?? \"\",\n snippet: row.snippet ?? row.content?.slice(0, 200) ?? \"\",\n score: row._relevance_score ?? (row._distance != null ? 1 / (1 + (row._distance ?? 0)) : 0.5),\n }));\n }\n\n private async tableHasCompatibleVectors(\n table: any,\n providerIdentity: EmbedProviderIdentity,\n execution?: SearchExecutionOptions,\n ): Promise<boolean> {\n try {\n const cached = this.vectorProviderCompatibility.get(table);\n if (cached?.providerIdentity === providerIdentity) return cached.compatible;\n const rows = await table.query().select([\"vector\", \"vectorProvider\"]).toArray();\n let compatible = rows.length > 0;\n for (const row of rows ?? []) {\n throwIfSearchAborted(execution, \"LanceDbBackend vector provider check aborted\");\n if (\n row.vectorProvider !== providerIdentity ||\n !this.isCompatibleStoredVector(row.vector)\n ) {\n compatible = false;\n break;\n }\n }\n this.vectorProviderCompatibility.set(table, { providerIdentity, compatible });\n return compatible;\n } catch (err) {\n if (isSearchAborted(execution)) throw err;\n log.debug(`LanceDbBackend vector provider check failed: ${err}`);\n return false;\n }\n }\n\n private rememberVectorProviderCompatibility(\n table: unknown,\n providerIdentity: EmbedProviderIdentity | null,\n compatible: boolean,\n ): void {\n if (!table || typeof table !== \"object\") return;\n if (!providerIdentity) {\n this.vectorProviderCompatibility.delete(table);\n return;\n }\n this.vectorProviderCompatibility.set(table, { providerIdentity, compatible });\n }\n\n private isExpectedDimensionVector(vector: number[] | null | undefined): vector is number[] {\n return Array.isArray(vector) && vector.length === this.embeddingDimension;\n }\n\n private isCompatibleStoredVector(vector: unknown): boolean {\n if (!vector || typeof vector !== \"object\") return false;\n const arr = Array.from(vector as ArrayLike<number>);\n return (\n arr.length === this.embeddingDimension &&\n arr.every((value) => Number.isFinite(value)) &&\n arr.some((value) => value !== 0)\n );\n }\n}\n\nfunction isMissingVectorProviderColumnError(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err);\n return /\\bvectorProvider\\b/i.test(message) &&\n /\\b(column|field|schema|missing|not found|not exist|does not exist|unknown)\\b/i.test(message);\n}\n"],"mappings":"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","names":["embedResult","results"]}
|
|
@@ -105,7 +105,7 @@ function validateEvalBenchmarkManifest(raw, options) {
|
|
|
105
105
|
}
|
|
106
106
|
return {
|
|
107
107
|
schemaVersion: 1,
|
|
108
|
-
benchmarkId: assertString(raw.benchmarkId, "benchmarkId"),
|
|
108
|
+
benchmarkId: assertSafeBenchmarkId(assertString(raw.benchmarkId, "benchmarkId")),
|
|
109
109
|
benchmarkType,
|
|
110
110
|
title: assertString(raw.title, "title"),
|
|
111
111
|
description: typeof raw.description === "string" && raw.description.trim().length > 0 ? raw.description.trim() : void 0,
|
|
@@ -897,4 +897,4 @@ export {
|
|
|
897
897
|
runEvalStoredBaselineCiGate,
|
|
898
898
|
runEvalBenchmarkCiGate
|
|
899
899
|
};
|
|
900
|
-
//# sourceMappingURL=chunk-
|
|
900
|
+
//# sourceMappingURL=chunk-3PY7VHV7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/evals.ts"],"sourcesContent":["import path from \"node:path\";\nimport { cp, mkdir, readFile, readdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { listJsonFiles, listNamedFiles, readJsonFile } from \"./json-store.js\";\n\nexport type EvalRunStatus = \"running\" | \"completed\" | \"failed\" | \"partial\";\n\nexport interface EvalBenchmarkCase {\n id: string;\n prompt: string;\n expectedSignals?: string[];\n notes?: string;\n}\n\nexport type EvalBenchmarkType = \"standard\" | \"memory-red-team\";\n\nexport interface EvalBenchmarkManifest {\n schemaVersion: 1;\n benchmarkId: string;\n benchmarkType?: EvalBenchmarkType;\n title: string;\n description?: string;\n tags?: string[];\n sourceLinks?: string[];\n attackClass?: string;\n targetSurface?: string;\n cases: EvalBenchmarkCase[];\n}\n\nexport interface EvalRunMetrics {\n recallPrecisionAtK?: number;\n actionOutcomeScore?: number;\n objectiveStateCoverage?: number;\n causalPathRecall?: number;\n trustViolationRate?: number;\n creationRecoveryScore?: number;\n}\n\nexport interface EvalRunSummary {\n schemaVersion: 1;\n runId: string;\n benchmarkId: string;\n status: EvalRunStatus;\n startedAt: string;\n completedAt?: string;\n totalCases: number;\n passedCases: number;\n failedCases: number;\n metrics?: EvalRunMetrics;\n notes?: string;\n gitRef?: string;\n}\n\nexport interface EvalShadowRecallRecord {\n schemaVersion: 1;\n traceId: string;\n recordedAt: string;\n sessionKey: string;\n promptHash: string;\n promptLength: number;\n retrievalQueryHash: string;\n retrievalQueryLength: number;\n recallMode: \"no_recall\" | \"minimal\" | \"full\" | \"graph_mode\";\n recallResultLimit: number;\n source: \"none\" | \"hot_qmd\" | \"hot_embedding\" | \"cold_fallback\" | \"recent_scan\";\n recalledMemoryCount: number;\n injected: boolean;\n contextChars: number;\n memoryIds: string[];\n policyVersion?: string;\n identityInjectionMode?: \"recovery_only\" | \"minimal\" | \"full\" | \"none\";\n identityInjectedChars?: number;\n identityInjectionTruncated?: boolean;\n durationMs: number;\n timings?: Record<string, string>;\n}\n\nexport interface EvalHarnessStatus {\n enabled: boolean;\n shadowModeEnabled: boolean;\n rootDir: string;\n benchmarkDir: string;\n runsDir: string;\n benchmarks: {\n total: number;\n valid: number;\n invalid: number;\n redTeam: number;\n totalCases: number;\n attackClasses: string[];\n tags: string[];\n targetSurfaces: string[];\n sourceLinks: string[];\n };\n runs: {\n total: number;\n invalid: number;\n completed: number;\n failed: number;\n partial: number;\n running: number;\n latestRunId?: string;\n latestBenchmarkId?: string;\n latestCompletedAt?: string;\n };\n shadows: {\n total: number;\n invalid: number;\n latestTraceId?: string;\n latestRecordedAt?: string;\n latestSessionKey?: string;\n };\n baselines: {\n enabled: boolean;\n total: number;\n invalid: number;\n latestSnapshotId?: string;\n latestCreatedAt?: string;\n latestBenchmarkCount?: number;\n };\n latestRun?: EvalRunSummary;\n latestShadow?: EvalShadowRecallRecord;\n latestBaseline?: EvalBaselineSnapshot;\n invalidBenchmarks: Array<{\n path: string;\n error: string;\n }>;\n invalidRuns: Array<{\n path: string;\n error: string;\n }>;\n invalidShadows: Array<{\n path: string;\n error: string;\n }>;\n invalidBaselines: Array<{\n path: string;\n error: string;\n }>;\n}\n\nexport interface EvalBenchmarkDelta {\n benchmarkId: string;\n baseRunId: string;\n candidateRunId: string;\n basePassRate: number;\n candidatePassRate: number;\n passRateDelta: number;\n metricDeltas: Partial<Record<keyof EvalRunMetrics, number>>;\n regressions: string[];\n improvements: string[];\n}\n\nexport interface EvalCiGateReport {\n passed: boolean;\n baseRootDir: string;\n candidateRootDir: string;\n comparedBenchmarks: number;\n missingCandidateBenchmarks: string[];\n invalidArtifacts: {\n base: {\n benchmarks: number;\n runs: number;\n shadows: number;\n };\n candidate: {\n benchmarks: number;\n runs: number;\n shadows: number;\n };\n };\n regressions: string[];\n improvements: string[];\n deltas: EvalBenchmarkDelta[];\n}\n\nexport interface EvalBaselineDeltaReport {\n passed: boolean;\n baselineSnapshotId: string;\n baselineCreatedAt: string;\n baselineSourceRootDir: string;\n candidateRootDir: string;\n comparedBenchmarks: number;\n missingCandidateBenchmarks: string[];\n invalidArtifacts: {\n candidate: {\n benchmarks: number;\n runs: number;\n shadows: number;\n baselines: number;\n };\n };\n regressions: string[];\n improvements: string[];\n deltas: EvalBenchmarkDelta[];\n markdownReport: string;\n}\n\nexport interface EvalStoredBaselineCiGateReport extends EvalBaselineDeltaReport {\n baseRootDir: string;\n baselineResolvedFrom: \"base\" | \"candidate\";\n}\n\nexport interface EvalBaselineSnapshotBenchmark {\n benchmarkId: string;\n runId: string;\n completedAt?: string;\n gitRef?: string;\n passRate: number;\n metrics?: EvalRunMetrics;\n}\n\nexport interface EvalBaselineSnapshot {\n schemaVersion: 1;\n snapshotId: string;\n createdAt: string;\n sourceRootDir: string;\n benchmarkCount: number;\n benchmarks: EvalBaselineSnapshotBenchmark[];\n notes?: string;\n gitRef?: string;\n}\n\nexport interface EvalBenchmarkPackSummary {\n sourcePath: string;\n manifestPath: string;\n benchmarkId: string;\n benchmarkType: EvalBenchmarkType;\n title: string;\n attackClass?: string;\n targetSurface?: string;\n totalCases: number;\n tags: string[];\n sourceLinks: string[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction assertString(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new Error(`${field} must be a non-empty string`);\n }\n return value.trim();\n}\n\nfunction optionalStringArray(value: unknown, field: string): string[] | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n throw new Error(`${field} must be an array of strings`);\n }\n const out = value\n .filter((item): item is string => typeof item === \"string\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n if (out.length !== value.length) {\n throw new Error(`${field} must be an array of non-empty strings`);\n }\n return out;\n}\n\nexport function resolveEvalStoreDir(memoryDir: string, overrideDir?: string): string {\n if (typeof overrideDir === \"string\" && overrideDir.trim().length > 0) {\n return overrideDir.trim();\n }\n return path.join(memoryDir, \"state\", \"evals\");\n}\n\nfunction assertSafePathSegment(value: string, field: string): string {\n if (value === \".\" || value === \"..\" || value.includes(\"/\") || value.includes(\"\\\\\")) {\n throw new Error(`${field} must be a safe path segment`);\n }\n return value;\n}\n\nfunction assertSafeBenchmarkId(benchmarkId: string): string {\n return assertSafePathSegment(benchmarkId, \"benchmarkId\");\n}\n\nconst ISO_UTC_TIMESTAMP_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\nfunction assertIsoTimestamp(value: unknown, field: string): string {\n const timestamp = assertString(value, field);\n if (!ISO_UTC_TIMESTAMP_RE.test(timestamp)) {\n throw new Error(`${field} must be a valid ISO timestamp`);\n }\n const parsed = Date.parse(timestamp);\n if (!Number.isFinite(parsed)) {\n throw new Error(`${field} must be a valid ISO timestamp`);\n }\n const normalized = new Date(parsed).toISOString();\n if (normalized !== timestamp) {\n throw new Error(`${field} must be a valid ISO timestamp`);\n }\n return normalized;\n}\n\nfunction assertNonNegativeInteger(value: unknown, field: string): number {\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${field} must be a non-negative integer`);\n }\n return parsed;\n}\n\nfunction assertPathWithin(rootDir: string, targetPath: string, field: string): void {\n const resolvedRoot = path.resolve(rootDir);\n const resolvedTarget = path.resolve(targetPath);\n const relative = path.relative(resolvedRoot, resolvedTarget);\n if (relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative))) {\n return;\n }\n throw new Error(`${field} must stay within ${rootDir}`);\n}\n\nexport function validateEvalBenchmarkManifest(\n raw: unknown,\n options?: { memoryRedTeamBenchEnabled?: boolean },\n): EvalBenchmarkManifest {\n if (!isRecord(raw)) throw new Error(\"benchmark manifest must be an object\");\n if (raw.schemaVersion !== 1) throw new Error(\"schemaVersion must be 1\");\n if (!Array.isArray(raw.cases)) throw new Error(\"cases must be an array\");\n const benchmarkTypeRaw =\n typeof raw.benchmarkType === \"string\" && raw.benchmarkType.trim().length > 0\n ? raw.benchmarkType.trim()\n : \"standard\";\n if (![\"standard\", \"memory-red-team\"].includes(benchmarkTypeRaw)) {\n throw new Error(\"benchmarkType must be one of standard|memory-red-team\");\n }\n\n const cases = raw.cases.map((item, index) => {\n if (!isRecord(item)) throw new Error(`cases[${index}] must be an object`);\n return {\n id: assertString(item.id, `cases[${index}].id`),\n prompt: assertString(item.prompt, `cases[${index}].prompt`),\n expectedSignals: optionalStringArray(item.expectedSignals, `cases[${index}].expectedSignals`),\n notes: typeof item.notes === \"string\" && item.notes.trim().length > 0 ? item.notes.trim() : undefined,\n } satisfies EvalBenchmarkCase;\n });\n\n const benchmarkType = benchmarkTypeRaw as EvalBenchmarkType;\n if (benchmarkType === \"memory-red-team\" && options?.memoryRedTeamBenchEnabled !== true) {\n throw new Error(\"memory-red-team benchmark packs require memoryRedTeamBenchEnabled\");\n }\n const attackClass =\n typeof raw.attackClass === \"string\" && raw.attackClass.trim().length > 0\n ? raw.attackClass.trim()\n : undefined;\n const targetSurface =\n typeof raw.targetSurface === \"string\" && raw.targetSurface.trim().length > 0\n ? raw.targetSurface.trim()\n : undefined;\n if (benchmarkType === \"memory-red-team\" && attackClass === undefined) {\n throw new Error(\"attackClass must be a non-empty string\");\n }\n if (benchmarkType === \"memory-red-team\" && targetSurface === undefined) {\n throw new Error(\"targetSurface must be a non-empty string\");\n }\n\n return {\n schemaVersion: 1,\n benchmarkId: assertSafeBenchmarkId(assertString(raw.benchmarkId, \"benchmarkId\")),\n benchmarkType,\n title: assertString(raw.title, \"title\"),\n description:\n typeof raw.description === \"string\" && raw.description.trim().length > 0\n ? raw.description.trim()\n : undefined,\n tags: optionalStringArray(raw.tags, \"tags\"),\n sourceLinks: optionalStringArray(raw.sourceLinks, \"sourceLinks\"),\n attackClass,\n targetSurface,\n cases,\n };\n}\n\nexport function validateEvalRunSummary(raw: unknown): EvalRunSummary {\n if (!isRecord(raw)) throw new Error(\"eval run summary must be an object\");\n if (raw.schemaVersion !== 1) throw new Error(\"schemaVersion must be 1\");\n const status = assertString(raw.status, \"status\");\n if (![\"running\", \"completed\", \"failed\", \"partial\"].includes(status)) {\n throw new Error(\"status must be one of running|completed|failed|partial\");\n }\n\n const totalCases = assertNonNegativeInteger(raw.totalCases, \"totalCases\");\n const passedCases = assertNonNegativeInteger(raw.passedCases, \"passedCases\");\n const failedCases = assertNonNegativeInteger(raw.failedCases, \"failedCases\");\n if (passedCases + failedCases > totalCases) {\n throw new Error(\"passedCases + failedCases must be less than or equal to totalCases\");\n }\n\n const metrics = parseOptionalEvalRunMetrics(raw.metrics);\n const completedAt =\n typeof raw.completedAt === \"string\" && raw.completedAt.trim().length > 0\n ? assertIsoTimestamp(raw.completedAt, \"completedAt\")\n : undefined;\n\n return {\n schemaVersion: 1,\n runId: assertString(raw.runId, \"runId\"),\n benchmarkId: assertString(raw.benchmarkId, \"benchmarkId\"),\n status: status as EvalRunStatus,\n startedAt: assertIsoTimestamp(raw.startedAt, \"startedAt\"),\n completedAt,\n totalCases,\n passedCases,\n failedCases,\n metrics,\n notes: typeof raw.notes === \"string\" && raw.notes.trim().length > 0 ? raw.notes.trim() : undefined,\n gitRef: typeof raw.gitRef === \"string\" && raw.gitRef.trim().length > 0 ? raw.gitRef.trim() : undefined,\n };\n}\n\nexport function validateEvalBaselineSnapshot(raw: unknown): EvalBaselineSnapshot {\n if (!isRecord(raw)) throw new Error(\"eval baseline snapshot must be an object\");\n if (raw.schemaVersion !== 1) throw new Error(\"schemaVersion must be 1\");\n if (!Array.isArray(raw.benchmarks)) throw new Error(\"benchmarks must be an array\");\n\n const benchmarks = raw.benchmarks.map((item, index) => {\n if (!isRecord(item)) throw new Error(`benchmarks[${index}] must be an object`);\n const passRate = Number(item.passRate);\n if (!Number.isFinite(passRate) || passRate < 0 || passRate > 1) {\n throw new Error(`benchmarks[${index}].passRate must be a number between 0 and 1`);\n }\n\n const metrics = parseOptionalEvalRunMetrics(item.metrics);\n\n return {\n benchmarkId: assertString(item.benchmarkId, `benchmarks[${index}].benchmarkId`),\n runId: assertString(item.runId, `benchmarks[${index}].runId`),\n completedAt:\n typeof item.completedAt === \"string\" && item.completedAt.trim().length > 0\n ? assertIsoTimestamp(item.completedAt, `benchmarks[${index}].completedAt`)\n : undefined,\n gitRef:\n typeof item.gitRef === \"string\" && item.gitRef.trim().length > 0\n ? item.gitRef.trim()\n : undefined,\n passRate,\n metrics,\n } satisfies EvalBaselineSnapshotBenchmark;\n });\n\n const benchmarkCount = Number(raw.benchmarkCount);\n if (!Number.isFinite(benchmarkCount) || benchmarkCount < 0) {\n throw new Error(\"benchmarkCount must be a non-negative number\");\n }\n if (benchmarkCount !== benchmarks.length) {\n throw new Error(\"benchmarkCount must match benchmarks.length\");\n }\n\n return {\n schemaVersion: 1,\n snapshotId: assertString(raw.snapshotId, \"snapshotId\"),\n createdAt: assertIsoTimestamp(raw.createdAt, \"createdAt\"),\n sourceRootDir: assertString(raw.sourceRootDir, \"sourceRootDir\"),\n benchmarkCount,\n benchmarks,\n notes: typeof raw.notes === \"string\" && raw.notes.trim().length > 0 ? raw.notes.trim() : undefined,\n gitRef: typeof raw.gitRef === \"string\" && raw.gitRef.trim().length > 0 ? raw.gitRef.trim() : undefined,\n };\n}\n\nfunction parseOptionalEvalRunMetrics(raw: unknown): EvalRunMetrics | undefined {\n if (!isRecord(raw)) return undefined;\n return {\n recallPrecisionAtK: typeof raw.recallPrecisionAtK === \"number\" ? raw.recallPrecisionAtK : undefined,\n actionOutcomeScore: typeof raw.actionOutcomeScore === \"number\" ? raw.actionOutcomeScore : undefined,\n objectiveStateCoverage: typeof raw.objectiveStateCoverage === \"number\" ? raw.objectiveStateCoverage : undefined,\n causalPathRecall: typeof raw.causalPathRecall === \"number\" ? raw.causalPathRecall : undefined,\n trustViolationRate: typeof raw.trustViolationRate === \"number\" ? raw.trustViolationRate : undefined,\n creationRecoveryScore: typeof raw.creationRecoveryScore === \"number\" ? raw.creationRecoveryScore : undefined,\n } satisfies EvalRunMetrics;\n}\n\nexport function validateEvalShadowRecallRecord(raw: unknown): EvalShadowRecallRecord {\n if (!isRecord(raw)) throw new Error(\"eval shadow recall record must be an object\");\n if (raw.schemaVersion !== 1) throw new Error(\"schemaVersion must be 1\");\n\n const recallMode = assertString(raw.recallMode, \"recallMode\");\n if (![\"no_recall\", \"minimal\", \"full\", \"graph_mode\"].includes(recallMode)) {\n throw new Error(\"recallMode must be one of no_recall|minimal|full|graph_mode\");\n }\n\n const source = assertString(raw.source, \"source\");\n if (![\"none\", \"hot_qmd\", \"hot_embedding\", \"cold_fallback\", \"recent_scan\"].includes(source)) {\n throw new Error(\"source must be one of none|hot_qmd|hot_embedding|cold_fallback|recent_scan\");\n }\n\n const promptLength = Number(raw.promptLength);\n const retrievalQueryLength = Number(raw.retrievalQueryLength);\n const recallResultLimit = Number(raw.recallResultLimit);\n const recalledMemoryCount = Number(raw.recalledMemoryCount);\n const contextChars = Number(raw.contextChars);\n const durationMs = Number(raw.durationMs);\n\n for (const [field, value] of [\n [\"promptLength\", promptLength],\n [\"retrievalQueryLength\", retrievalQueryLength],\n [\"recallResultLimit\", recallResultLimit],\n [\"recalledMemoryCount\", recalledMemoryCount],\n [\"contextChars\", contextChars],\n [\"durationMs\", durationMs],\n ] as const) {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`${field} must be a non-negative number`);\n }\n }\n\n const memoryIds = optionalStringArray(raw.memoryIds, \"memoryIds\") ?? [];\n if (typeof raw.injected !== \"boolean\") throw new Error(\"injected must be a boolean\");\n\n let timings: Record<string, string> | undefined;\n if (raw.timings !== undefined) {\n if (!isRecord(raw.timings)) throw new Error(\"timings must be an object of strings\");\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(raw.timings)) {\n if (typeof value !== \"string\") throw new Error(\"timings must be an object of strings\");\n out[key] = value;\n }\n timings = out;\n }\n\n const identityInjectionModeRaw =\n typeof raw.identityInjectionMode === \"string\" && raw.identityInjectionMode.trim().length > 0\n ? raw.identityInjectionMode.trim()\n : undefined;\n if (\n identityInjectionModeRaw !== undefined &&\n ![\"recovery_only\", \"minimal\", \"full\", \"none\"].includes(identityInjectionModeRaw)\n ) {\n throw new Error(\"identityInjectionMode must be one of recovery_only|minimal|full|none\");\n }\n\n return {\n schemaVersion: 1,\n traceId: assertSafePathSegment(assertString(raw.traceId, \"traceId\"), \"traceId\"),\n recordedAt: assertIsoTimestamp(raw.recordedAt, \"recordedAt\"),\n sessionKey: assertString(raw.sessionKey, \"sessionKey\"),\n promptHash: assertString(raw.promptHash, \"promptHash\"),\n promptLength,\n retrievalQueryHash: assertString(raw.retrievalQueryHash, \"retrievalQueryHash\"),\n retrievalQueryLength,\n recallMode: recallMode as EvalShadowRecallRecord[\"recallMode\"],\n recallResultLimit,\n source: source as EvalShadowRecallRecord[\"source\"],\n recalledMemoryCount,\n injected: raw.injected,\n contextChars,\n memoryIds,\n policyVersion:\n typeof raw.policyVersion === \"string\" && raw.policyVersion.trim().length > 0\n ? raw.policyVersion.trim()\n : undefined,\n identityInjectionMode: identityInjectionModeRaw as EvalShadowRecallRecord[\"identityInjectionMode\"],\n identityInjectedChars:\n typeof raw.identityInjectedChars === \"number\" && Number.isFinite(raw.identityInjectedChars)\n ? raw.identityInjectedChars\n : undefined,\n identityInjectionTruncated:\n typeof raw.identityInjectionTruncated === \"boolean\" ? raw.identityInjectionTruncated : undefined,\n durationMs,\n timings,\n };\n}\n\ninterface EvalStoreSnapshot {\n status: EvalHarnessStatus;\n manifests: EvalBenchmarkManifest[];\n runs: EvalRunSummary[];\n shadows: EvalShadowRecallRecord[];\n baselines: EvalBaselineSnapshot[];\n}\n\ninterface EvalStoreSnapshotOptions {\n rootDir: string;\n enabled: boolean;\n shadowModeEnabled: boolean;\n baselineSnapshotsEnabled?: boolean;\n memoryRedTeamBenchEnabled?: boolean;\n}\n\nconst LOWER_IS_BETTER_METRICS = new Set<keyof EvalRunMetrics>([\"trustViolationRate\"]);\n\nfunction computePassRate(run: EvalRunSummary): number {\n return run.totalCases > 0 ? run.passedCases / run.totalCases : 0;\n}\n\nfunction latestCompletedRunsByBenchmark(runs: EvalRunSummary[]): Map<string, EvalRunSummary> {\n const sorted = [...runs]\n .filter((run) => run.status === \"completed\")\n .sort((a, b) => {\n const aTime = Date.parse(a.completedAt ?? a.startedAt);\n const bTime = Date.parse(b.completedAt ?? b.startedAt);\n return (Number.isNaN(bTime) ? 0 : bTime) - (Number.isNaN(aTime) ? 0 : aTime);\n });\n const out = new Map<string, EvalRunSummary>();\n for (const run of sorted) {\n if (!out.has(run.benchmarkId)) {\n out.set(run.benchmarkId, run);\n }\n }\n return out;\n}\n\nfunction compareMetricDeltas(\n baseMetrics: EvalRunMetrics | undefined,\n candidateMetrics: EvalRunMetrics | undefined,\n): {\n deltas: Partial<Record<keyof EvalRunMetrics, number>>;\n regressions: string[];\n improvements: string[];\n} {\n const deltas: Partial<Record<keyof EvalRunMetrics, number>> = {};\n const regressions: string[] = [];\n const improvements: string[] = [];\n if (!baseMetrics || !candidateMetrics) {\n return { deltas, regressions, improvements };\n }\n\n for (const metric of Object.keys(baseMetrics) as Array<keyof EvalRunMetrics>) {\n const baseValue = baseMetrics[metric];\n const candidateValue = candidateMetrics[metric];\n if (typeof baseValue !== \"number\" || typeof candidateValue !== \"number\") continue;\n const delta = candidateValue - baseValue;\n deltas[metric] = delta;\n if (delta === 0) continue;\n const lowerIsBetter = LOWER_IS_BETTER_METRICS.has(metric);\n const improved = lowerIsBetter ? delta < 0 : delta > 0;\n const summary = `${metric} ${baseValue} -> ${candidateValue}`;\n if (improved) {\n improvements.push(summary);\n } else {\n regressions.push(summary);\n }\n }\n\n return { deltas, regressions, improvements };\n}\n\nfunction formatEvalBaselineDeltaMarkdown(report: EvalBaselineDeltaReport): string {\n const lines = [\n \"# Eval Baseline Delta Report\",\n \"\",\n `- Passed: ${report.passed ? \"yes\" : \"no\"}`,\n `- Baseline snapshot: ${report.baselineSnapshotId}`,\n `- Baseline created: ${report.baselineCreatedAt}`,\n `- Baseline source root: ${report.baselineSourceRootDir}`,\n `- Candidate root: ${report.candidateRootDir}`,\n `- Benchmarks compared: ${report.comparedBenchmarks}`,\n ];\n\n if (report.missingCandidateBenchmarks.length > 0) {\n lines.push(`- Missing candidate benchmarks: ${report.missingCandidateBenchmarks.join(\", \")}`);\n }\n\n lines.push(\n `- Invalid candidate artifacts: benchmarks=${report.invalidArtifacts.candidate.benchmarks}, runs=${report.invalidArtifacts.candidate.runs}, shadows=${report.invalidArtifacts.candidate.shadows}, baselines=${report.invalidArtifacts.candidate.baselines}`,\n \"\",\n \"## Regressions\",\n );\n if (report.regressions.length === 0) {\n lines.push(\"- none\");\n } else {\n for (const regression of report.regressions) lines.push(`- ${regression}`);\n }\n\n lines.push(\"\", \"## Improvements\");\n if (report.improvements.length === 0) {\n lines.push(\"- none\");\n } else {\n for (const improvement of report.improvements) lines.push(`- ${improvement}`);\n }\n\n lines.push(\"\", \"## Benchmark Deltas\");\n if (report.deltas.length === 0) {\n lines.push(\"- none\");\n } else {\n for (const delta of report.deltas) {\n lines.push(\n `- ${delta.benchmarkId}: passRate ${delta.basePassRate} -> ${delta.candidatePassRate} (delta ${delta.passRateDelta})`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nasync function collectEvalStoreSnapshot(options: EvalStoreSnapshotOptions): Promise<EvalStoreSnapshot> {\n const rootDir = options.rootDir;\n const benchmarkDir = path.join(rootDir, \"benchmarks\");\n const runsDir = path.join(rootDir, \"runs\");\n const shadowDir = path.join(rootDir, \"shadow\");\n const baselineDir = path.join(rootDir, \"baselines\");\n const benchmarkFiles = await listNamedFiles(benchmarkDir, \"manifest.json\");\n const runFiles = await listJsonFiles(runsDir);\n const shadowFiles = await listJsonFiles(shadowDir);\n const baselineFiles = await listJsonFiles(baselineDir);\n\n const invalidBenchmarks: Array<{ path: string; error: string }> = [];\n const invalidRuns: Array<{ path: string; error: string }> = [];\n const invalidShadows: Array<{ path: string; error: string }> = [];\n const invalidBaselines: Array<{ path: string; error: string }> = [];\n const manifests: EvalBenchmarkManifest[] = [];\n\n for (const filePath of benchmarkFiles) {\n try {\n manifests.push(\n validateEvalBenchmarkManifest(await readJsonFile(filePath), {\n memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled,\n }),\n );\n } catch (error) {\n invalidBenchmarks.push({\n path: filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n const runs: EvalRunSummary[] = [];\n for (const filePath of runFiles) {\n try {\n runs.push(validateEvalRunSummary(await readJsonFile(filePath)));\n } catch (error) {\n invalidRuns.push({\n path: filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n const shadows: EvalShadowRecallRecord[] = [];\n for (const filePath of shadowFiles) {\n try {\n shadows.push(validateEvalShadowRecallRecord(await readJsonFile(filePath)));\n } catch (error) {\n invalidShadows.push({\n path: filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n const baselines: EvalBaselineSnapshot[] = [];\n for (const filePath of baselineFiles) {\n try {\n baselines.push(validateEvalBaselineSnapshot(await readJsonFile(filePath)));\n } catch (error) {\n invalidBaselines.push({\n path: filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n runs.sort((a, b) => {\n const aTime = Date.parse(a.completedAt ?? a.startedAt);\n const bTime = Date.parse(b.completedAt ?? b.startedAt);\n return (Number.isNaN(bTime) ? 0 : bTime) - (Number.isNaN(aTime) ? 0 : aTime);\n });\n shadows.sort((a, b) => b.recordedAt.localeCompare(a.recordedAt));\n baselines.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n\n const tags = new Set<string>();\n const attackClasses = new Set<string>();\n const sourceLinks = new Set<string>();\n const targetSurfaces = new Set<string>();\n let totalCases = 0;\n let redTeam = 0;\n for (const manifest of manifests) {\n totalCases += manifest.cases.length;\n if (manifest.benchmarkType === \"memory-red-team\") {\n redTeam += 1;\n if (manifest.attackClass) attackClasses.add(manifest.attackClass);\n if (manifest.targetSurface) targetSurfaces.add(manifest.targetSurface);\n }\n for (const tag of manifest.tags ?? []) tags.add(tag);\n for (const link of manifest.sourceLinks ?? []) sourceLinks.add(link);\n }\n\n return {\n status: {\n enabled: options.enabled,\n shadowModeEnabled: options.shadowModeEnabled,\n rootDir,\n benchmarkDir,\n runsDir,\n benchmarks: {\n total: benchmarkFiles.length,\n valid: manifests.length,\n invalid: invalidBenchmarks.length,\n redTeam,\n totalCases,\n attackClasses: [...attackClasses].sort(),\n tags: [...tags].sort(),\n targetSurfaces: [...targetSurfaces].sort(),\n sourceLinks: [...sourceLinks].sort(),\n },\n runs: {\n total: runFiles.length,\n invalid: invalidRuns.length,\n completed: runs.filter((run) => run.status === \"completed\").length,\n failed: runs.filter((run) => run.status === \"failed\").length,\n partial: runs.filter((run) => run.status === \"partial\").length,\n running: runs.filter((run) => run.status === \"running\").length,\n latestRunId: runs[0]?.runId,\n latestBenchmarkId: runs[0]?.benchmarkId,\n latestCompletedAt: runs[0]?.completedAt,\n },\n shadows: {\n total: shadowFiles.length,\n invalid: invalidShadows.length,\n latestTraceId: shadows[0]?.traceId,\n latestRecordedAt: shadows[0]?.recordedAt,\n latestSessionKey: shadows[0]?.sessionKey,\n },\n baselines: {\n enabled: options.baselineSnapshotsEnabled === true,\n total: baselineFiles.length,\n invalid: invalidBaselines.length,\n latestSnapshotId: baselines[0]?.snapshotId,\n latestCreatedAt: baselines[0]?.createdAt,\n latestBenchmarkCount: baselines[0]?.benchmarkCount,\n },\n latestRun: runs[0],\n latestShadow: shadows[0],\n latestBaseline: baselines[0],\n invalidBenchmarks,\n invalidRuns,\n invalidShadows,\n invalidBaselines,\n },\n manifests,\n runs,\n shadows,\n baselines,\n };\n}\n\nasync function resolveBenchmarkManifestPath(sourcePath: string): Promise<{ sourceKind: \"file\" | \"directory\"; manifestPath: string }> {\n const info = await stat(sourcePath);\n if (info.isDirectory()) {\n return {\n sourceKind: \"directory\",\n manifestPath: path.join(sourcePath, \"manifest.json\"),\n };\n }\n if (info.isFile()) {\n return {\n sourceKind: \"file\",\n manifestPath: sourcePath,\n };\n }\n throw new Error(\"benchmark pack source must be a file or directory\");\n}\n\nexport async function validateEvalBenchmarkPack(\n sourcePath: string,\n options?: { memoryRedTeamBenchEnabled?: boolean },\n): Promise<EvalBenchmarkPackSummary> {\n const trimmedSourcePath = sourcePath.trim();\n if (trimmedSourcePath.length === 0) {\n throw new Error(\"benchmark pack path must be a non-empty string\");\n }\n const { manifestPath } = await resolveBenchmarkManifestPath(trimmedSourcePath);\n const manifest = validateEvalBenchmarkManifest(await readJsonFile(manifestPath), {\n memoryRedTeamBenchEnabled: options?.memoryRedTeamBenchEnabled,\n });\n return {\n sourcePath: trimmedSourcePath,\n manifestPath,\n benchmarkId: assertSafeBenchmarkId(manifest.benchmarkId),\n benchmarkType: manifest.benchmarkType ?? \"standard\",\n title: manifest.title,\n attackClass: manifest.attackClass,\n targetSurface: manifest.targetSurface,\n totalCases: manifest.cases.length,\n tags: [...(manifest.tags ?? [])],\n sourceLinks: [...(manifest.sourceLinks ?? [])],\n };\n}\n\nexport async function importEvalBenchmarkPack(options: {\n sourcePath: string;\n memoryDir: string;\n evalStoreDir?: string;\n force?: boolean;\n memoryRedTeamBenchEnabled?: boolean;\n}): Promise<EvalBenchmarkPackSummary & { targetDir: string; overwritten: boolean }> {\n const summary = await validateEvalBenchmarkPack(options.sourcePath, {\n memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled,\n });\n const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);\n const benchmarkDir = path.join(rootDir, \"benchmarks\");\n const targetDir = path.join(benchmarkDir, summary.benchmarkId);\n const { sourceKind, manifestPath } = await resolveBenchmarkManifestPath(summary.sourcePath);\n\n let overwritten = false;\n try {\n await stat(targetDir);\n if (options.force !== true) {\n throw new Error(`benchmark pack already exists at ${targetDir}; rerun with force to replace it`);\n }\n overwritten = true;\n await rm(targetDir, { recursive: true, force: true });\n } catch (error) {\n if (!(error instanceof Error) || !(\"code\" in error) || (error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n\n await mkdir(benchmarkDir, { recursive: true });\n if (sourceKind === \"directory\") {\n await cp(summary.sourcePath, targetDir, { recursive: true });\n } else {\n await mkdir(targetDir, { recursive: true });\n await cp(manifestPath, path.join(targetDir, \"manifest.json\"));\n }\n\n return {\n ...summary,\n targetDir,\n overwritten,\n };\n}\n\nexport async function recordEvalShadowRecall(options: {\n memoryDir: string;\n evalStoreDir?: string;\n record: EvalShadowRecallRecord;\n}): Promise<string> {\n const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);\n const validated = validateEvalShadowRecallRecord(options.record);\n const day = validated.recordedAt.slice(0, 10);\n const shadowRoot = path.join(rootDir, \"shadow\");\n const shadowDir = path.join(shadowRoot, day);\n const targetPath = path.join(shadowDir, `${validated.traceId}.json`);\n assertPathWithin(shadowRoot, targetPath, \"shadow recall record path\");\n await mkdir(shadowDir, { recursive: true });\n await writeFile(targetPath, JSON.stringify(validated, null, 2), \"utf-8\");\n return targetPath;\n}\n\nexport async function getEvalHarnessStatus(options: {\n memoryDir: string;\n evalStoreDir?: string;\n enabled: boolean;\n shadowModeEnabled: boolean;\n baselineSnapshotsEnabled?: boolean;\n memoryRedTeamBenchEnabled?: boolean;\n}): Promise<EvalHarnessStatus> {\n return (\n await collectEvalStoreSnapshot({\n rootDir: resolveEvalStoreDir(options.memoryDir, options.evalStoreDir),\n enabled: options.enabled,\n shadowModeEnabled: options.shadowModeEnabled,\n baselineSnapshotsEnabled: options.baselineSnapshotsEnabled,\n memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled,\n })\n ).status;\n}\n\nexport async function createEvalBaselineSnapshot(options: {\n memoryDir: string;\n evalStoreDir?: string;\n baselineSnapshotsEnabled: boolean;\n snapshotId: string;\n createdAt?: string;\n notes?: string;\n gitRef?: string;\n}): Promise<{ targetPath: string; snapshot: EvalBaselineSnapshot }> {\n if (options.baselineSnapshotsEnabled !== true) {\n throw new Error(\"benchmark baseline snapshots are disabled\");\n }\n\n const snapshotId = assertSafePathSegment(assertString(options.snapshotId, \"snapshotId\"), \"snapshotId\");\n const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);\n const store = await collectEvalStoreSnapshot({\n rootDir,\n enabled: true,\n shadowModeEnabled: true,\n baselineSnapshotsEnabled: true,\n memoryRedTeamBenchEnabled: true,\n });\n const latestRuns = latestCompletedRunsByBenchmark(store.runs);\n const benchmarks = [...latestRuns.values()]\n .sort((a, b) => a.benchmarkId.localeCompare(b.benchmarkId))\n .map((run) => ({\n benchmarkId: run.benchmarkId,\n runId: run.runId,\n completedAt: run.completedAt,\n gitRef: run.gitRef,\n passRate: computePassRate(run),\n metrics: run.metrics,\n } satisfies EvalBaselineSnapshotBenchmark));\n\n const snapshot = validateEvalBaselineSnapshot({\n schemaVersion: 1,\n snapshotId,\n createdAt: options.createdAt ?? new Date().toISOString(),\n sourceRootDir: rootDir,\n benchmarkCount: benchmarks.length,\n benchmarks,\n notes: options.notes,\n gitRef: options.gitRef,\n });\n\n const targetPath = path.join(rootDir, \"baselines\", `${snapshot.snapshotId}.json`);\n await mkdir(path.dirname(targetPath), { recursive: true });\n await writeFile(targetPath, JSON.stringify(snapshot, null, 2), \"utf-8\");\n return { targetPath, snapshot };\n}\n\nexport async function runEvalBaselineDeltaReport(options: {\n memoryDir: string;\n evalStoreDir?: string;\n benchmarkDeltaReporterEnabled: boolean;\n snapshotId: string;\n}): Promise<EvalBaselineDeltaReport> {\n if (options.benchmarkDeltaReporterEnabled !== true) {\n throw new Error(\"benchmark delta reporter is disabled\");\n }\n\n const snapshotId = assertSafePathSegment(assertString(options.snapshotId, \"snapshotId\"), \"snapshotId\");\n const candidateRootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);\n const candidateSnapshot = await collectEvalStoreSnapshot({\n rootDir: candidateRootDir,\n enabled: true,\n shadowModeEnabled: true,\n baselineSnapshotsEnabled: true,\n memoryRedTeamBenchEnabled: true,\n });\n const baselineSnapshot = candidateSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId);\n if (!baselineSnapshot) {\n throw new Error(`benchmark baseline snapshot not found: ${snapshotId}`);\n }\n\n return buildEvalBaselineDeltaReport({\n baselineSnapshot,\n candidateSnapshot,\n });\n}\n\nexport async function runEvalStoredBaselineCiGate(options: {\n baseMemoryDir?: string;\n baseEvalStoreDir: string;\n candidateMemoryDir?: string;\n candidateEvalStoreDir: string;\n snapshotId: string;\n}): Promise<EvalStoredBaselineCiGateReport> {\n const snapshotId = assertSafePathSegment(assertString(options.snapshotId, \"snapshotId\"), \"snapshotId\");\n const baseRootDir = resolveEvalStoreDir(options.baseMemoryDir ?? options.baseEvalStoreDir, options.baseEvalStoreDir);\n const candidateRootDir = resolveEvalStoreDir(\n options.candidateMemoryDir ?? options.candidateEvalStoreDir,\n options.candidateEvalStoreDir,\n );\n const [baseSnapshot, candidateSnapshot] = await Promise.all([\n collectEvalStoreSnapshot({\n rootDir: baseRootDir,\n enabled: true,\n shadowModeEnabled: true,\n baselineSnapshotsEnabled: true,\n memoryRedTeamBenchEnabled: true,\n }),\n collectEvalStoreSnapshot({\n rootDir: candidateRootDir,\n enabled: true,\n shadowModeEnabled: true,\n baselineSnapshotsEnabled: true,\n memoryRedTeamBenchEnabled: true,\n }),\n ]);\n const baselineSnapshot =\n baseSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId) ??\n candidateSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId);\n if (!baselineSnapshot) {\n throw new Error(`benchmark baseline snapshot not found: ${snapshotId}`);\n }\n\n return {\n baseRootDir,\n baselineResolvedFrom: baseSnapshot.baselines.some((snapshot) => snapshot.snapshotId === snapshotId) ? \"base\" : \"candidate\",\n ...buildEvalBaselineDeltaReport({\n baselineSnapshot,\n candidateSnapshot,\n }),\n };\n}\n\nfunction buildEvalBaselineDeltaReport(options: {\n baselineSnapshot: EvalBaselineSnapshot;\n candidateSnapshot: EvalStoreSnapshot;\n}): EvalBaselineDeltaReport {\n const { baselineSnapshot, candidateSnapshot } = options;\n\n const regressions: string[] = [];\n const improvements: string[] = [];\n\n if (candidateSnapshot.status.invalidBenchmarks.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);\n }\n if (candidateSnapshot.status.invalidRuns.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidRuns.length} invalid run summary file(s)`);\n }\n if (candidateSnapshot.status.invalidShadows.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidShadows.length} invalid shadow record(s)`);\n }\n if (candidateSnapshot.status.invalidBaselines.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidBaselines.length} invalid baseline snapshot file(s)`);\n }\n\n const candidateRuns = latestCompletedRunsByBenchmark(candidateSnapshot.runs);\n const baselineBenchmarks = new Map(\n baselineSnapshot.benchmarks.map((benchmark) => [benchmark.benchmarkId, benchmark] as const),\n );\n const missingCandidateBenchmarks = [...baselineBenchmarks.keys()]\n .filter((benchmarkId) => !candidateRuns.has(benchmarkId))\n .sort();\n for (const benchmarkId of missingCandidateBenchmarks) {\n regressions.push(`candidate is missing latest completed benchmark run for ${benchmarkId}`);\n }\n\n const deltas: EvalBenchmarkDelta[] = [];\n for (const benchmarkId of [...baselineBenchmarks.keys()].sort()) {\n const baseBenchmark = baselineBenchmarks.get(benchmarkId);\n const candidateRun = candidateRuns.get(benchmarkId);\n if (!baseBenchmark || !candidateRun) continue;\n\n const passRateDelta = computePassRate(candidateRun) - baseBenchmark.passRate;\n const delta: EvalBenchmarkDelta = {\n benchmarkId,\n baseRunId: baseBenchmark.runId,\n candidateRunId: candidateRun.runId,\n basePassRate: baseBenchmark.passRate,\n candidatePassRate: computePassRate(candidateRun),\n passRateDelta,\n metricDeltas: {},\n regressions: [],\n improvements: [],\n };\n\n if (passRateDelta < 0) {\n delta.regressions.push(`passRate ${baseBenchmark.passRate} -> ${delta.candidatePassRate}`);\n regressions.push(`${benchmarkId} pass rate regressed (${baseBenchmark.passRate} -> ${delta.candidatePassRate})`);\n } else if (passRateDelta > 0) {\n delta.improvements.push(`passRate ${baseBenchmark.passRate} -> ${delta.candidatePassRate}`);\n improvements.push(`${benchmarkId} pass rate improved (${baseBenchmark.passRate} -> ${delta.candidatePassRate})`);\n }\n\n const metricDelta = compareMetricDeltas(baseBenchmark.metrics, candidateRun.metrics);\n delta.metricDeltas = metricDelta.deltas;\n for (const regression of metricDelta.regressions) {\n delta.regressions.push(regression);\n regressions.push(`${benchmarkId} ${regression}`);\n }\n for (const improvement of metricDelta.improvements) {\n delta.improvements.push(improvement);\n improvements.push(`${benchmarkId} ${improvement}`);\n }\n deltas.push(delta);\n }\n\n const report: EvalBaselineDeltaReport = {\n passed: regressions.length === 0,\n baselineSnapshotId: baselineSnapshot.snapshotId,\n baselineCreatedAt: baselineSnapshot.createdAt,\n baselineSourceRootDir: baselineSnapshot.sourceRootDir,\n candidateRootDir: candidateSnapshot.status.rootDir,\n comparedBenchmarks: deltas.length,\n missingCandidateBenchmarks,\n invalidArtifacts: {\n candidate: {\n benchmarks: candidateSnapshot.status.invalidBenchmarks.length,\n runs: candidateSnapshot.status.invalidRuns.length,\n shadows: candidateSnapshot.status.invalidShadows.length,\n baselines: candidateSnapshot.status.invalidBaselines.length,\n },\n },\n regressions,\n improvements,\n deltas,\n markdownReport: \"\",\n };\n report.markdownReport = formatEvalBaselineDeltaMarkdown(report);\n return report;\n}\n\nfunction resolveRequiredEvalStoreRoot(options: { memoryDir?: string; evalStoreDir?: string }, label: string): string {\n if (typeof options.evalStoreDir === \"string\" && options.evalStoreDir.trim().length > 0) {\n return options.evalStoreDir.trim();\n }\n if (typeof options.memoryDir === \"string\" && options.memoryDir.trim().length > 0) {\n return resolveEvalStoreDir(options.memoryDir.trim());\n }\n throw new Error(`${label} requires memoryDir or evalStoreDir`);\n}\n\nexport async function runEvalBenchmarkCiGate(options: {\n baseMemoryDir?: string;\n candidateMemoryDir?: string;\n baseEvalStoreDir?: string;\n candidateEvalStoreDir?: string;\n}): Promise<EvalCiGateReport> {\n const baseRootDir = resolveRequiredEvalStoreRoot(\n { memoryDir: options.baseMemoryDir, evalStoreDir: options.baseEvalStoreDir },\n \"base\",\n );\n const candidateRootDir = resolveRequiredEvalStoreRoot(\n { memoryDir: options.candidateMemoryDir, evalStoreDir: options.candidateEvalStoreDir },\n \"candidate\",\n );\n const baseSnapshot = await collectEvalStoreSnapshot({\n rootDir: baseRootDir,\n enabled: true,\n shadowModeEnabled: true,\n memoryRedTeamBenchEnabled: true,\n });\n const candidateSnapshot = await collectEvalStoreSnapshot({\n rootDir: candidateRootDir,\n enabled: true,\n shadowModeEnabled: true,\n memoryRedTeamBenchEnabled: true,\n });\n\n const regressions: string[] = [];\n const improvements: string[] = [];\n\n if (baseSnapshot.status.invalidBenchmarks.length > 0) {\n regressions.push(`base store has ${baseSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);\n }\n if (baseSnapshot.status.invalidRuns.length > 0) {\n regressions.push(`base store has ${baseSnapshot.status.invalidRuns.length} invalid run summary file(s)`);\n }\n if (baseSnapshot.status.invalidShadows.length > 0) {\n regressions.push(`base store has ${baseSnapshot.status.invalidShadows.length} invalid shadow record(s)`);\n }\n if (candidateSnapshot.status.invalidBenchmarks.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);\n }\n if (candidateSnapshot.status.invalidRuns.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidRuns.length} invalid run summary file(s)`);\n }\n if (candidateSnapshot.status.invalidShadows.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidShadows.length} invalid shadow record(s)`);\n }\n\n const baseRuns = latestCompletedRunsByBenchmark(baseSnapshot.runs);\n const candidateRuns = latestCompletedRunsByBenchmark(candidateSnapshot.runs);\n const missingCandidateBenchmarks = [...baseRuns.keys()]\n .filter((benchmarkId) => !candidateRuns.has(benchmarkId))\n .sort();\n for (const benchmarkId of missingCandidateBenchmarks) {\n regressions.push(`candidate is missing latest completed benchmark run for ${benchmarkId}`);\n }\n\n const deltas: EvalBenchmarkDelta[] = [];\n for (const benchmarkId of [...baseRuns.keys()].sort()) {\n const baseRun = baseRuns.get(benchmarkId);\n const candidateRun = candidateRuns.get(benchmarkId);\n if (!baseRun || !candidateRun) continue;\n\n const basePassRate = computePassRate(baseRun);\n const candidatePassRate = computePassRate(candidateRun);\n const passRateDelta = candidatePassRate - basePassRate;\n const delta: EvalBenchmarkDelta = {\n benchmarkId,\n baseRunId: baseRun.runId,\n candidateRunId: candidateRun.runId,\n basePassRate,\n candidatePassRate,\n passRateDelta,\n metricDeltas: {},\n regressions: [],\n improvements: [],\n };\n\n if (passRateDelta < 0) {\n delta.regressions.push(`passRate ${basePassRate} -> ${candidatePassRate}`);\n regressions.push(`${benchmarkId} pass rate regressed (${basePassRate} -> ${candidatePassRate})`);\n } else if (passRateDelta > 0) {\n delta.improvements.push(`passRate ${basePassRate} -> ${candidatePassRate}`);\n improvements.push(`${benchmarkId} pass rate improved (${basePassRate} -> ${candidatePassRate})`);\n }\n\n const metricDelta = compareMetricDeltas(baseRun.metrics, candidateRun.metrics);\n delta.metricDeltas = metricDelta.deltas;\n for (const regression of metricDelta.regressions) {\n delta.regressions.push(regression);\n regressions.push(`${benchmarkId} ${regression}`);\n }\n for (const improvement of metricDelta.improvements) {\n delta.improvements.push(improvement);\n improvements.push(`${benchmarkId} ${improvement}`);\n }\n deltas.push(delta);\n }\n\n return {\n passed: regressions.length === 0,\n baseRootDir: baseSnapshot.status.rootDir,\n candidateRootDir: candidateSnapshot.status.rootDir,\n comparedBenchmarks: deltas.length,\n missingCandidateBenchmarks,\n invalidArtifacts: {\n base: {\n benchmarks: baseSnapshot.status.invalidBenchmarks.length,\n runs: baseSnapshot.status.invalidRuns.length,\n shadows: baseSnapshot.status.invalidShadows.length,\n },\n candidate: {\n benchmarks: candidateSnapshot.status.invalidBenchmarks.length,\n runs: candidateSnapshot.status.invalidRuns.length,\n shadows: candidateSnapshot.status.invalidShadows.length,\n },\n },\n regressions,\n improvements,\n deltas,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseXrayFormat
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PSUB67YB.js";
|
|
4
4
|
import {
|
|
5
5
|
RECALL_DISCLOSURE_LEVELS,
|
|
6
6
|
isRecallDisclosure
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4R4KTDIE.js";
|
|
8
8
|
|
|
9
9
|
// src/recall-xray-cli.ts
|
|
10
10
|
function parseXrayDisclosureFlag(value) {
|
|
@@ -50,4 +50,4 @@ export {
|
|
|
50
50
|
parseXrayBudgetFlag,
|
|
51
51
|
parseXrayCliOptions
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
53
|
+
//# sourceMappingURL=chunk-3QSU4NFF.js.map
|
|
@@ -17,7 +17,7 @@ function isCalendarDateValid(year, month, day) {
|
|
|
17
17
|
return day <= maxDay;
|
|
18
18
|
}
|
|
19
19
|
function parseStrictCliDate(value, flagName) {
|
|
20
|
-
const shape = /^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|[+-]\d{2}
|
|
20
|
+
const shape = /^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(?:Z|([+-])(\d{2}):(\d{2}))?)?$/;
|
|
21
21
|
const match = value.match(shape);
|
|
22
22
|
if (!match) {
|
|
23
23
|
throw new Error(
|
|
@@ -42,6 +42,15 @@ function parseStrictCliDate(value, flagName) {
|
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
if (match[8] !== void 0) {
|
|
46
|
+
const offsetHour = Number(match[9]);
|
|
47
|
+
const offsetMinute = Number(match[10]);
|
|
48
|
+
if (offsetHour > 14 || offsetMinute > 59 || offsetHour === 14 && offsetMinute !== 0) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Invalid ${flagName} value "${value}": timezone offset out of range.`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
45
54
|
const d = new Date(value);
|
|
46
55
|
if (!Number.isFinite(d.getTime())) {
|
|
47
56
|
throw new Error(
|
|
@@ -390,4 +399,4 @@ export {
|
|
|
390
399
|
renderPatternsList,
|
|
391
400
|
renderPatternExplain
|
|
392
401
|
};
|
|
393
|
-
//# sourceMappingURL=chunk-
|
|
402
|
+
//# sourceMappingURL=chunk-3T74IZB3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/training-export/date-parse.ts","../src/patterns-cli.ts"],"sourcesContent":["/**\n * Strict ISO 8601 date parsing for training-export CLI flags.\n *\n * Extracted from `cli.ts` so that both the canonical CLI (in\n * `@remnic/core`) and the thin front-end CLI (in `@remnic/cli`) can share\n * the same validator without duplicating the overflow/timezone rules.\n *\n * The parser rejects:\n * - Non-ISO strings (e.g. \"12/25/2026\", \"Dec 25 2026\")\n * - Calendar overflows (Feb 30, Feb 29 in non-leap years, Apr 31, etc.)\n * regardless of timezone suffix\n * - Out-of-range time components (hour >= 24, minute >= 60, second >= 60)\n * - Out-of-range timezone offsets (beyond ±14:00, or offset minute >= 60)\n *\n * Calendar overflow is validated structurally on the Y-M-D components, so\n * results are independent of the host's local timezone.\n */\n\n/**\n * Days in each month (1-indexed). February is 28 here; leap-year handling\n * is applied by `isCalendarDateValid` below.\n */\nconst DAYS_IN_MONTH = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nfunction isLeapYear(year: number): boolean {\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n/**\n * True iff `year-month-day` is a valid Gregorian calendar date. Input\n * numbers must be integer-valued; month is 1-12, day is 1-31 nominally.\n */\nexport function isCalendarDateValid(\n year: number,\n month: number,\n day: number,\n): boolean {\n if (\n !Number.isInteger(year) ||\n !Number.isInteger(month) ||\n !Number.isInteger(day)\n ) {\n return false;\n }\n if (month < 1 || month > 12) return false;\n if (day < 1) return false;\n const maxDay = month === 2 && isLeapYear(year) ? 29 : DAYS_IN_MONTH[month];\n return day <= maxDay;\n}\n\n/**\n * Parse a strict ISO 8601 date string, rejecting malformed inputs, calendar\n * overflows, and out-of-range time components with a descriptive error.\n *\n * Accepted forms:\n * YYYY-MM-DD\n * YYYY-MM-DDTHH:mm:ss (naive / local time)\n * YYYY-MM-DDTHH:mm:ss.sssZ (UTC)\n * YYYY-MM-DDTHH:mm:ss+HH:MM (with timezone offset)\n * YYYY-MM-DDTHH:mm:ss.sss-HH:MM (with timezone offset)\n *\n * `flagName` is included in the error message so users can identify which\n * input failed (e.g. `--since` vs. `--until`).\n */\nexport function parseStrictCliDate(value: string, flagName: string): Date {\n // 1. Shape check: must begin YYYY-MM-DD and use ISO 8601 structure.\n // This rejects \"12/25/2026\", \"December 25, 2026\", RFC 2822, etc.\n const shape =\n /^(\\d{4})-(\\d{2})-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{1,9}))?)?(?:Z|([+-])(\\d{2}):(\\d{2}))?)?$/;\n const match = value.match(shape);\n if (!match) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\": expected ISO 8601 format (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss[.sss][Z|±HH:MM]).`,\n );\n }\n\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n\n // 2. Structural calendar validation. This rejects Feb 31, Feb 29 in\n // non-leap years, Apr 31, etc. regardless of the timezone suffix, so\n // \"2026-02-31T00:00:00+05:30\" is rejected the same way as \"2026-02-31Z\".\n if (!isCalendarDateValid(year, month, day)) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\": date components overflow (e.g. month has fewer days). Provide a valid calendar date.`,\n );\n }\n\n // 3. Optional time-component validation.\n // JavaScript's Date cannot represent a leap second: `:60` is silently\n // normalised to `:00` of the following minute, which would make a\n // \"strict\" validator return a different timestamp than the user\n // requested. Reject second == 60 outright so a strict parse cannot\n // round-trip to a different clock value.\n if (match[4] !== undefined) {\n const hour = Number(match[4]);\n const minute = Number(match[5]);\n const second = match[6] !== undefined ? Number(match[6]) : 0;\n if (hour > 23 || minute > 59 || second > 59) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\": time components out of range.`,\n );\n }\n }\n\n // 4. Timezone offset validation.\n // Date accepts offset hours beyond the real-world UTC offset range and\n // normalizes impossible offsets into a shifted instant. Reject those\n // before constructing the Date so the CLI cannot silently apply them.\n if (match[8] !== undefined) {\n const offsetHour = Number(match[9]);\n const offsetMinute = Number(match[10]);\n if (\n offsetHour > 14 ||\n offsetMinute > 59 ||\n (offsetHour === 14 && offsetMinute !== 0)\n ) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\": timezone offset out of range.`,\n );\n }\n }\n\n // 5. Finally parse via Date for the actual timestamp value. At this point\n // we've already validated structure and calendar correctness, so any\n // remaining NaN (extremely unlikely) still fails closed.\n const d = new Date(value);\n if (!Number.isFinite(d.getTime())) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\". Provide an ISO 8601 date string (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss).`,\n );\n }\n\n return d;\n}\n","/**\n * `remnic patterns` CLI helpers (issue #687 PR 4/4).\n *\n * Pure functions that:\n *\n * 1. Validate `--limit`, `--category`, `--since`, `--format` for\n * `remnic patterns list` and `--format` for\n * `remnic patterns explain <id>` (CLAUDE.md rules 14 + 51 — flags\n * throw listed-options errors instead of silently defaulting).\n *\n * 2. Filter the memory corpus to canonical memories produced by the\n * pattern-reinforcement maintenance job from issue #687 PR 2/4\n * (`reinforcement_count > 0`) and sort them by reinforcement\n * count, with `last_reinforced_at` (then `id`) as stable\n * tiebreakers (CLAUDE.md rule 19).\n *\n * 3. Reconstruct a single canonical's full picture: its\n * `derived_from` provenance chain (PR 2/4 stamps these), the\n * cluster members it absorbed (memories pointing at it via\n * `supersededBy`), and the canonical body so operators can read\n * it inline.\n *\n * 4. Render `text` (default) / `markdown` / `json` output for both\n * commands. The CLI handler in `cli.ts` stays thin and delegates\n * formatting here so HTTP / MCP surfaces (if added later) can\n * reuse the same renderers (CLAUDE.md rule 22 — never fork\n * formatting).\n */\n\nimport type { MemoryCategory, MemoryFile } from \"./types.js\";\nimport { DERIVED_FROM_MEMORY_ID_RE } from \"./consolidation-operator.js\";\nimport { parseStrictCliDate } from \"./training-export/date-parse.js\";\n\nexport const PATTERNS_OUTPUT_FORMATS = [\"text\", \"markdown\", \"json\"] as const;\nexport type PatternsOutputFormat = (typeof PATTERNS_OUTPUT_FORMATS)[number];\n\n// ───────────────────────────────────────────────────────────────────────────\n// Flag validation\n// ───────────────────────────────────────────────────────────────────────────\n\n/**\n * Validate `--format <fmt>`. Throws a listed-options error for any\n * value not in `PATTERNS_OUTPUT_FORMATS`. Returns `\"text\"` when the\n * value is `undefined` (no flag supplied).\n */\nexport function parsePatternsFormat(value: unknown): PatternsOutputFormat {\n if (value === undefined || value === null) return \"text\";\n if (\n typeof value !== \"string\" ||\n !(PATTERNS_OUTPUT_FORMATS as readonly string[]).includes(value)\n ) {\n throw new Error(\n `--format expects one of ${PATTERNS_OUTPUT_FORMATS.join(\", \")}; got ${JSON.stringify(value)}`,\n );\n }\n return value as PatternsOutputFormat;\n}\n\n/**\n * Validate `--limit <N>`. Must be a positive integer. Returns\n * `undefined` when the flag is absent (the caller falls back to a\n * default).\n */\nexport function parsePatternsLimit(value: unknown): number | undefined {\n if (value === undefined || value === null) return undefined;\n const parsed = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(\n `--limit expects a positive integer; got ${JSON.stringify(value)}`,\n );\n }\n return parsed;\n}\n\n/**\n * Validate `--category <list>`. Accepts a comma-separated list of\n * non-empty trimmed tokens. Returns the deduplicated list, or\n * `undefined` when no flag was supplied. CLAUDE.md rules 14 + 51:\n * `--category` with no value or with a value that resolves to zero\n * tokens is rejected.\n */\nexport function parsePatternsCategory(value: unknown): string[] | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"string\") {\n throw new Error(\n `--category expects a comma-separated list of category names; got ${JSON.stringify(value)}`,\n );\n }\n const parts = value\n .split(\",\")\n .map((part) => part.trim())\n .filter((part) => part.length > 0);\n if (parts.length === 0) {\n throw new Error(\n `--category expects at least one non-empty category name; got ${JSON.stringify(value)}`,\n );\n }\n // Deduplicate while preserving first-seen order.\n const seen = new Set<string>();\n const unique: string[] = [];\n for (const part of parts) {\n if (!seen.has(part)) {\n seen.add(part);\n unique.push(part);\n }\n }\n return unique;\n}\n\n/**\n * Validate `--since <ISO>`. Delegates to `parseStrictCliDate` which\n * enforces a strict ISO 8601 shape and rejects calendar overflows and\n * non-ISO formats (e.g. \"12/25/2026\", \"Dec 25 2026\") that bare\n * `Date.parse()` would silently accept. Returns the canonical ISO\n * string (round-trip through `toISOString`) so downstream comparisons\n * use a consistent form.\n */\nexport function parsePatternsSince(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new Error(\n `--since expects an ISO 8601 timestamp (e.g. 2026-04-01T00:00:00Z); got ${JSON.stringify(value)}`,\n );\n }\n // parseStrictCliDate throws with a descriptive message on invalid input.\n return parseStrictCliDate(value.trim(), \"--since\").toISOString();\n}\n\nexport interface ParsedPatternsListOptions {\n format: PatternsOutputFormat;\n limit?: number;\n categories?: string[];\n sinceIso?: string;\n}\n\nexport interface ParsedPatternsExplainOptions {\n format: PatternsOutputFormat;\n}\n\n/**\n * Validate the full option bag for `remnic patterns list`. Extracted\n * from the CLI handler so validation can be unit-tested without\n * booting an orchestrator (CLAUDE.md rules 14 + 51).\n */\nexport function parsePatternsListOptions(\n options: Record<string, unknown>,\n): ParsedPatternsListOptions {\n const format = parsePatternsFormat(options.format);\n const limit = parsePatternsLimit(options.limit);\n const categories = parsePatternsCategory(options.category);\n const sinceIso = parsePatternsSince(options.since);\n return {\n format,\n ...(limit !== undefined ? { limit } : {}),\n ...(categories !== undefined ? { categories } : {}),\n ...(sinceIso !== undefined ? { sinceIso } : {}),\n };\n}\n\n/**\n * Validate `remnic patterns explain` options + positional id. Throws\n * when `<memoryId>` is missing or empty.\n */\nexport function parsePatternsExplainOptions(\n rawId: unknown,\n options: Record<string, unknown>,\n): { id: string } & ParsedPatternsExplainOptions {\n if (typeof rawId !== \"string\" || rawId.trim().length === 0) {\n throw new Error(\"patterns explain: <memoryId> is required and must be non-empty\");\n }\n const format = parsePatternsFormat(options.format);\n return { id: rawId.trim(), format };\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Core list / explain behavior\n// ───────────────────────────────────────────────────────────────────────────\n\nexport interface PatternListRow {\n id: string;\n category: MemoryCategory;\n reinforcementCount: number;\n lastReinforcedAt?: string;\n status: string;\n /** First non-empty content line, trimmed to ~120 chars for the table. */\n preview: string;\n /** Full path on disk (relative to memoryDir) for operators who want to inspect the file. */\n path: string;\n}\n\nconst DEFAULT_LIST_LIMIT = 50;\n\n/**\n * Filter, sort, and slice the memory corpus down to the rows the\n * `remnic patterns list` command should print.\n *\n * Rules (each one is exercised by `tests/cli/patterns.test.ts`):\n *\n * - Memories without `reinforcement_count` (or with a count <= 0) are\n * dropped — these are not pattern canonicals.\n * - When `categories` is supplied, only memories whose\n * `frontmatter.category` is in the list survive.\n * - When `sinceIso` is supplied, only memories whose\n * `last_reinforced_at` is `>= sinceIso` survive. Memories without\n * `last_reinforced_at` are dropped under `--since` (PR 2/4 always\n * stamps the timestamp alongside the count, so a missing timestamp\n * means a malformed file the operator should not see in this view).\n * - Sort by `reinforcement_count DESC`, then `last_reinforced_at\n * DESC`, then `id ASC` for a stable, deterministic order\n * (CLAUDE.md rule 19).\n * - Apply `limit` (default 50).\n */\nexport function collectPatternMemories(\n memories: readonly MemoryFile[],\n opts: ParsedPatternsListOptions,\n): PatternListRow[] {\n const sinceMs =\n opts.sinceIso !== undefined ? Date.parse(opts.sinceIso) : undefined;\n const categorySet =\n opts.categories !== undefined ? new Set(opts.categories) : undefined;\n\n const rows: PatternListRow[] = [];\n for (const memory of memories) {\n const fm = memory.frontmatter;\n const count = fm.reinforcement_count;\n if (typeof count !== \"number\" || !Number.isInteger(count) || count <= 0) {\n continue;\n }\n if (categorySet !== undefined && !categorySet.has(fm.category)) {\n continue;\n }\n if (sinceMs !== undefined) {\n if (typeof fm.last_reinforced_at !== \"string\") continue;\n const ts = Date.parse(fm.last_reinforced_at);\n if (!Number.isFinite(ts) || ts < sinceMs) continue;\n }\n rows.push({\n id: fm.id,\n category: fm.category,\n reinforcementCount: count,\n ...(fm.last_reinforced_at !== undefined\n ? { lastReinforcedAt: fm.last_reinforced_at }\n : {}),\n status: fm.status ?? \"active\",\n preview: extractPreview(memory.content),\n path: memory.path,\n });\n }\n\n rows.sort((a, b) => {\n if (b.reinforcementCount !== a.reinforcementCount) {\n return b.reinforcementCount - a.reinforcementCount;\n }\n // Guard NaN: malformed date strings make Date.parse return NaN, which\n // breaks the sort contract (NaN comparator return == non-deterministic\n // ordering). Treat invalid/missing timestamps as 0 (oldest possible).\n const aRaw = a.lastReinforcedAt ? Date.parse(a.lastReinforcedAt) : NaN;\n const bRaw = b.lastReinforcedAt ? Date.parse(b.lastReinforcedAt) : NaN;\n const aTs = Number.isFinite(aRaw) ? aRaw : 0;\n const bTs = Number.isFinite(bRaw) ? bRaw : 0;\n if (bTs !== aTs) return bTs - aTs;\n if (a.id < b.id) return -1;\n if (a.id > b.id) return 1;\n return 0;\n });\n\n const limit = opts.limit ?? DEFAULT_LIST_LIMIT;\n return rows.slice(0, limit);\n}\n\nexport interface PatternDerivedFromEntry {\n /** Raw `\"<path>:<version>\"` reference exactly as stored in `derived_from`. */\n ref: string;\n /** Source memory id, or the path component for older `path:version` references. */\n path: string;\n /** Page-version number component for older `path:version` references. */\n version: number | null;\n /** True when an older path-version reference had an invalid version component. */\n malformed?: boolean;\n}\n\nexport interface PatternClusterMember {\n id: string;\n status: string;\n supersededAt?: string;\n path: string;\n preview: string;\n}\n\nexport interface PatternExplainDetail {\n id: string;\n category: MemoryCategory;\n reinforcementCount: number;\n lastReinforcedAt?: string;\n status: string;\n derivedVia?: string;\n /** Full canonical body (frontmatter stripped). */\n canonicalContent: string;\n canonicalPath: string;\n /** Parsed `derived_from` chain — empty when PR 2/4 did not stamp it. */\n derivedFrom: PatternDerivedFromEntry[];\n /** Memories whose `supersededBy === <id>`, sorted by `supersededAt DESC` then `id ASC`. */\n clusterMembers: PatternClusterMember[];\n}\n\n/**\n * Build the structured detail object for a single canonical. Returns\n * `null` when the memory is not found or has never been touched by\n * pattern reinforcement (i.e., no `reinforcement_count`). The CLI\n * handler then prints a clean \"not a pattern\" error rather than\n * leaking an empty document.\n */\nexport function explainPatternMemory(\n memories: readonly MemoryFile[],\n id: string,\n): PatternExplainDetail | null {\n const canonical = memories.find((m) => m.frontmatter.id === id);\n if (!canonical) return null;\n const fm = canonical.frontmatter;\n const count = fm.reinforcement_count;\n if (typeof count !== \"number\" || !Number.isInteger(count) || count <= 0) {\n return null;\n }\n\n const derivedFrom: PatternDerivedFromEntry[] = (fm.derived_from ?? []).map(\n (ref) => {\n const lastColon = ref.lastIndexOf(\":\");\n const pathLikeRef = looksLikeDerivedFromPath(ref);\n if (lastColon >= 0) {\n const path = ref.slice(0, lastColon);\n const versionStr = ref.slice(lastColon + 1);\n if (\n looksLikeDerivedFromPath(path) &&\n /^\\d+$/.test(versionStr)\n ) {\n return { ref, path, version: Number(versionStr) };\n }\n if (!pathLikeRef && DERIVED_FROM_MEMORY_ID_RE.test(ref)) {\n return { ref, path: ref, version: null };\n }\n return { ref, path: ref, version: null, malformed: true };\n }\n if (DERIVED_FROM_MEMORY_ID_RE.test(ref)) {\n return {\n ref,\n path: ref,\n version: null,\n };\n }\n return { ref, path: ref, version: null, malformed: true };\n },\n );\n\n const members: PatternClusterMember[] = [];\n for (const m of memories) {\n if (m.frontmatter.supersededBy === id) {\n members.push({\n id: m.frontmatter.id,\n status: m.frontmatter.status ?? \"active\",\n ...(m.frontmatter.supersededAt !== undefined\n ? { supersededAt: m.frontmatter.supersededAt }\n : {}),\n path: m.path,\n preview: extractPreview(m.content),\n });\n }\n }\n members.sort((a, b) => {\n // Guard NaN: same rationale as collectPatternMemories sort — malformed\n // supersededAt strings must not produce a NaN return from the comparator.\n const aRaw = a.supersededAt ? Date.parse(a.supersededAt) : NaN;\n const bRaw = b.supersededAt ? Date.parse(b.supersededAt) : NaN;\n const aTs = Number.isFinite(aRaw) ? aRaw : 0;\n const bTs = Number.isFinite(bRaw) ? bRaw : 0;\n if (bTs !== aTs) return bTs - aTs;\n if (a.id < b.id) return -1;\n if (a.id > b.id) return 1;\n return 0;\n });\n\n return {\n id: fm.id,\n category: fm.category,\n reinforcementCount: count,\n ...(fm.last_reinforced_at !== undefined\n ? { lastReinforcedAt: fm.last_reinforced_at }\n : {}),\n status: fm.status ?? \"active\",\n ...(fm.derived_via !== undefined ? { derivedVia: fm.derived_via } : {}),\n canonicalContent: canonical.content.trim(),\n canonicalPath: canonical.path,\n derivedFrom,\n clusterMembers: members,\n };\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Renderers\n// ───────────────────────────────────────────────────────────────────────────\n\nexport function renderPatternsList(\n rows: readonly PatternListRow[],\n format: PatternsOutputFormat,\n): string {\n if (format === \"json\") {\n return JSON.stringify({ rows }, null, 2);\n }\n if (rows.length === 0) {\n if (format === \"markdown\") {\n return \"# Pattern memories\\n\\n_No reinforced patterns found._\\n\";\n }\n return \"No reinforced patterns found.\";\n }\n if (format === \"markdown\") {\n const lines: string[] = [\"# Pattern memories\", \"\"];\n lines.push(\"| Count | ID | Category | Last reinforced | Preview |\");\n lines.push(\"| --- | --- | --- | --- | --- |\");\n for (const row of rows) {\n const last = row.lastReinforcedAt ?? \"—\";\n const preview = escapePipes(row.preview);\n lines.push(\n `| ${row.reinforcementCount} | \\`${row.id}\\` | ${row.category} | ${last} | ${preview} |`,\n );\n }\n return lines.join(\"\\n\") + \"\\n\";\n }\n // text\n const lines: string[] = [];\n lines.push(`Pattern memories (${rows.length}):`);\n lines.push(\"\");\n for (const row of rows) {\n const last = row.lastReinforcedAt ?? \"—\";\n lines.push(\n ` [${row.reinforcementCount}x] ${row.id} (${row.category}, last_reinforced=${last}, status=${row.status})`,\n );\n if (row.preview.length > 0) {\n lines.push(` ${row.preview}`);\n }\n lines.push(` path: ${row.path}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderPatternExplain(\n detail: PatternExplainDetail,\n format: PatternsOutputFormat,\n): string {\n if (format === \"json\") {\n return JSON.stringify(detail, null, 2);\n }\n const last = detail.lastReinforcedAt ?? \"—\";\n const derivedVia = detail.derivedVia ?? \"—\";\n if (format === \"markdown\") {\n const lines: string[] = [];\n lines.push(`# Pattern: \\`${detail.id}\\``);\n lines.push(\"\");\n lines.push(`- **Reinforcement count:** ${detail.reinforcementCount}`);\n lines.push(`- **Last reinforced:** ${last}`);\n lines.push(`- **Category:** ${detail.category}`);\n lines.push(`- **Status:** ${detail.status}`);\n lines.push(`- **Derived via:** ${derivedVia}`);\n lines.push(`- **Path:** \\`${detail.canonicalPath}\\``);\n lines.push(\"\");\n lines.push(\"## Canonical content\");\n lines.push(\"\");\n lines.push(\"```\");\n lines.push(detail.canonicalContent);\n lines.push(\"```\");\n lines.push(\"\");\n lines.push(`## Derived from (${detail.derivedFrom.length})`);\n lines.push(\"\");\n if (detail.derivedFrom.length === 0) {\n lines.push(\"_No derived_from entries recorded._\");\n } else {\n for (const entry of detail.derivedFrom) {\n const versionStr =\n entry.version !== null\n ? ` v${entry.version}`\n : entry.malformed\n ? \" (malformed)\"\n : \"\";\n lines.push(`- \\`${entry.path}\\`${versionStr}`);\n }\n }\n lines.push(\"\");\n lines.push(`## Cluster members (${detail.clusterMembers.length})`);\n lines.push(\"\");\n if (detail.clusterMembers.length === 0) {\n lines.push(\"_No superseded members reference this canonical._\");\n } else {\n for (const member of detail.clusterMembers) {\n const ts = member.supersededAt ?? \"—\";\n lines.push(`- \\`${member.id}\\` (status=${member.status}, supersededAt=${ts})`);\n if (member.preview.length > 0) {\n lines.push(` - ${escapePipes(member.preview)}`);\n }\n }\n }\n return lines.join(\"\\n\") + \"\\n\";\n }\n // text\n const lines: string[] = [];\n lines.push(`Pattern: ${detail.id}`);\n lines.push(` reinforcement_count: ${detail.reinforcementCount}`);\n lines.push(` last_reinforced_at: ${last}`);\n lines.push(` category: ${detail.category}`);\n lines.push(` status: ${detail.status}`);\n lines.push(` derived_via: ${derivedVia}`);\n lines.push(` path: ${detail.canonicalPath}`);\n lines.push(\"\");\n lines.push(\"Canonical content:\");\n for (const line of detail.canonicalContent.split(\"\\n\")) {\n lines.push(` ${line}`);\n }\n lines.push(\"\");\n lines.push(`Derived from (${detail.derivedFrom.length}):`);\n if (detail.derivedFrom.length === 0) {\n lines.push(\" (none)\");\n } else {\n for (const entry of detail.derivedFrom) {\n const versionStr =\n entry.version !== null\n ? ` v${entry.version}`\n : entry.malformed\n ? \" (malformed)\"\n : \"\";\n lines.push(` - ${entry.path}${versionStr}`);\n }\n }\n lines.push(\"\");\n lines.push(`Cluster members (${detail.clusterMembers.length}):`);\n if (detail.clusterMembers.length === 0) {\n lines.push(\" (none)\");\n } else {\n for (const member of detail.clusterMembers) {\n const ts = member.supersededAt ?? \"—\";\n lines.push(` - ${member.id} (status=${member.status}, supersededAt=${ts})`);\n if (member.preview.length > 0) {\n lines.push(` ${member.preview}`);\n }\n }\n }\n return lines.join(\"\\n\");\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Internal helpers\n// ───────────────────────────────────────────────────────────────────────────\n\nfunction extractPreview(content: string): string {\n const trimmed = content.trim();\n if (trimmed.length === 0) return \"\";\n const firstLine = trimmed.split(\"\\n\").find((line) => line.trim().length > 0) ?? \"\";\n const collapsed = firstLine.trim().replace(/\\s+/g, \" \");\n if (collapsed.length <= 120) return collapsed;\n return collapsed.slice(0, 117) + \"...\";\n}\n\nfunction looksLikeDerivedFromPath(value: string): boolean {\n return value.includes(\"/\") || value.includes(\".\");\n}\n\n/**\n * Escape characters that would break a Markdown table cell:\n * - backslashes first (so the `\\|` escape below isn't double-escaped)\n * - then pipe characters\n *\n * CodeQL \"Incomplete string escaping or encoding\": backslash must be\n * escaped before pipe so that a literal `\\` in content isn't\n * misinterpreted as part of a `\\|` escape sequence.\n */\nfunction escapePipes(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\");\n}\n"],"mappings":"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","names":["lines"]}
|
|
@@ -205,11 +205,16 @@ function parseRollbackManifestEntry(raw, index) {
|
|
|
205
205
|
if (raw.contentHash !== void 0 && (typeof raw.contentHash !== "string" || !/^[a-f0-9]{64}$/u.test(raw.contentHash))) {
|
|
206
206
|
throw new Error(`rollback manifest entry ${index} has an invalid contentHash`);
|
|
207
207
|
}
|
|
208
|
+
const rawMode = raw.mode;
|
|
209
|
+
if (rawMode !== void 0 && (typeof rawMode !== "number" || !Number.isInteger(rawMode) || rawMode < 0 || rawMode > 511)) {
|
|
210
|
+
throw new Error(`rollback manifest entry ${index} has an invalid mode`);
|
|
211
|
+
}
|
|
208
212
|
return {
|
|
209
213
|
targetPath: raw.targetPath,
|
|
210
214
|
...raw.backupPath === void 0 ? {} : { backupPath: raw.backupPath },
|
|
211
215
|
...raw.createdByMigration === void 0 ? {} : { createdByMigration: raw.createdByMigration },
|
|
212
|
-
...raw.contentHash === void 0 ? {} : { contentHash: raw.contentHash }
|
|
216
|
+
...raw.contentHash === void 0 ? {} : { contentHash: raw.contentHash },
|
|
217
|
+
...rawMode === void 0 ? {} : { mode: rawMode }
|
|
213
218
|
};
|
|
214
219
|
}
|
|
215
220
|
function parseRollbackManifest(raw, manifestPath) {
|
|
@@ -350,7 +355,8 @@ async function validateRollbackManifestEntries(manifest, homeDir, options) {
|
|
|
350
355
|
targetPath,
|
|
351
356
|
...backupPath === void 0 ? {} : { backupPath },
|
|
352
357
|
...entry.createdByMigration === void 0 ? {} : { createdByMigration: entry.createdByMigration },
|
|
353
|
-
...entry.contentHash === void 0 ? {} : { contentHash: entry.contentHash }
|
|
358
|
+
...entry.contentHash === void 0 ? {} : { contentHash: entry.contentHash },
|
|
359
|
+
...entry.mode === void 0 ? {} : { mode: entry.mode }
|
|
354
360
|
});
|
|
355
361
|
}
|
|
356
362
|
return validated;
|
|
@@ -518,14 +524,14 @@ async function backupFile(targetPath, originalContent, homeDir, manifest, persis
|
|
|
518
524
|
}
|
|
519
525
|
const backupPath = connectorBackupPathForTarget(targetPath, homeDir);
|
|
520
526
|
await ensureParent(backupPath);
|
|
527
|
+
const originalMode = isRemnicTokenStorePath(targetPath, homeDir) ? TOKEN_STORE_MODE : (await stat(targetPath)).mode & 511;
|
|
521
528
|
if (isRemnicTokenStorePath(targetPath, homeDir)) {
|
|
522
529
|
await writeOwnerOnlyFile(backupPath, originalContent);
|
|
523
530
|
} else {
|
|
524
|
-
const originalMode = (await stat(targetPath)).mode & 511;
|
|
525
531
|
await writeFile(backupPath, originalContent, { encoding: "utf8", mode: originalMode });
|
|
526
532
|
await chmod(backupPath, originalMode);
|
|
527
533
|
}
|
|
528
|
-
manifest.entries.push({ targetPath, backupPath });
|
|
534
|
+
manifest.entries.push({ targetPath, backupPath, mode: originalMode });
|
|
529
535
|
await persistManifest?.();
|
|
530
536
|
}
|
|
531
537
|
async function recordCreatedPath(filePath, manifest, persistManifest) {
|
|
@@ -763,9 +769,8 @@ async function rollbackFromEngramMigration(options) {
|
|
|
763
769
|
await assertExistingRegularFileNoFollow(entry.backupPath, "rollback manifest backup");
|
|
764
770
|
await ensureParent(entry.targetPath);
|
|
765
771
|
await copyFile(entry.backupPath, entry.targetPath);
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
}
|
|
772
|
+
const restoreMode = isRemnicTokenStorePath(entry.targetPath, homeDir) ? TOKEN_STORE_MODE : entry.mode ?? (await lstat(entry.backupPath)).mode & 511;
|
|
773
|
+
await chmod(entry.targetPath, restoreMode);
|
|
769
774
|
restored.push(entry.targetPath);
|
|
770
775
|
continue;
|
|
771
776
|
}
|
|
@@ -879,4 +884,4 @@ export {
|
|
|
879
884
|
rollbackFromEngramMigration,
|
|
880
885
|
migrateFromEngram
|
|
881
886
|
};
|
|
882
|
-
//# sourceMappingURL=chunk-
|
|
887
|
+
//# sourceMappingURL=chunk-4HFJQCJZ.js.map
|