@remnic/core 9.7.14 → 9.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +13 -6
- package/dist/access-admin-ops-surface.js +88 -74
- package/dist/access-audit.js +2 -2
- package/dist/access-boundary.d.ts +35 -17
- package/dist/access-boundary.js +89 -77
- package/dist/access-citation.d.ts +28 -0
- package/dist/access-citation.js +9 -0
- package/dist/access-cli.js +197 -181
- package/dist/access-cli.js.map +1 -1
- package/dist/access-errors.d.ts +16 -1
- package/dist/access-errors.js +7 -3
- package/dist/access-http.d.ts +25 -19
- package/dist/access-http.js +103 -90
- package/dist/access-identity-continuity-surface.d.ts +13 -8
- package/dist/access-identity-continuity-surface.js +88 -74
- package/dist/access-lcm-surface.d.ts +16 -9
- package/dist/access-lcm-surface.js +88 -74
- package/dist/access-mcp.d.ts +23 -16
- package/dist/access-mcp.js +99 -87
- package/dist/access-memory-search-fanout.d.ts +93 -0
- package/dist/access-memory-search-fanout.js +18 -0
- package/dist/access-observe-write-surface.d.ts +26 -8
- package/dist/access-observe-write-surface.js +88 -74
- package/dist/access-operations-batch.js +95 -83
- package/dist/access-operations.d.ts +26 -19
- package/dist/access-operations.js +97 -85
- package/dist/access-recall-concurrency.d.ts +250 -0
- package/dist/access-recall-concurrency.js +157 -0
- package/dist/access-recall-response.d.ts +130 -0
- package/dist/access-recall-response.js +147 -0
- package/dist/access-recall-surface.d.ts +15 -7
- package/dist/access-recall-surface.js +88 -74
- package/dist/access-schema.d.ts +34 -34
- package/dist/access-schema.js +8 -6
- package/dist/{access-service-CPhSnLOH.d.ts → access-service-DEL4qCrc.d.ts} +25 -32
- package/dist/access-service.d.ts +13 -6
- package/dist/access-service.js +92 -75
- package/dist/access-surface-catalog.d.ts +23 -16
- package/dist/access-surface-catalog.js +1 -0
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-token-capabilities.d.ts +2 -1
- package/dist/access-token-capabilities.js +4 -2
- package/dist/action-confidence.d.ts +3 -1
- package/dist/active-memory-bridge.d.ts +3 -1
- package/dist/active-memory-bridge.js +4 -4
- package/dist/active-recall.d.ts +4 -1
- package/dist/active-recall.js +23 -13
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/{auto-sync-AAMTVZMK.js → auto-sync-UZG3XQZ5.js} +14 -8
- package/dist/{auto-sync-AAMTVZMK.js.map → auto-sync-UZG3XQZ5.js.map} +1 -1
- package/dist/behavior-learner.d.ts +3 -1
- package/dist/behavior-signals.d.ts +3 -1
- package/dist/bootstrap.d.ts +12 -7
- package/dist/bootstrap.js +2 -2
- package/dist/bounded-jsonl-state.d.ts +54 -0
- package/dist/bounded-jsonl-state.js +10 -0
- package/dist/boxes.js +2 -2
- package/dist/briefing.d.ts +5 -2
- package/dist/briefing.js +37 -27
- package/dist/buffer-surprise-report.d.ts +3 -1
- package/dist/buffer.d.ts +60 -2
- package/dist/buffer.js +3 -3
- package/dist/bulk-import/index.d.ts +5 -3
- package/dist/calibration.d.ts +3 -1
- package/dist/calibration.js +6 -6
- package/dist/capabilities.d.ts +7 -7
- package/dist/capabilities.js +1 -1
- package/dist/{capsule-crypto-CZJSLEFG.js → capsule-crypto-YO5QJ6L3.js} +3 -3
- package/dist/capsule-crypto-YO5QJ6L3.js.map +1 -0
- package/dist/{capsule-merge-Z2HUO6IK.js → capsule-merge-5KKJQBWQ.js} +4 -4
- package/dist/{catalog-uX9sT9ws.d.ts → catalog-BWqHb5HT.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +3 -1
- package/dist/causal-behavior.js +6 -6
- package/dist/causal-chain.js +4 -4
- package/dist/causal-consolidation.d.ts +3 -1
- package/dist/causal-consolidation.js +46 -37
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +6 -6
- package/dist/causal-trajectory-graph.d.ts +3 -1
- package/dist/causal-trajectory-graph.js +1 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-A3GOMRJG.js → chunk-23L3IXFD.js} +2 -2
- package/dist/chunk-2CGLBUW3.js +15 -0
- package/dist/chunk-2CGLBUW3.js.map +1 -0
- package/dist/{chunk-MRHFJV44.js → chunk-2DQ2XREU.js} +2 -2
- package/dist/{chunk-ASKEM4AR.js → chunk-2EJOEICD.js} +1823 -1483
- package/dist/chunk-2EJOEICD.js.map +1 -0
- package/dist/{chunk-L2B3EE7B.js → chunk-2QMKMVHH.js} +2 -2
- package/dist/{chunk-6CALL5VN.js → chunk-2UFO7X4Q.js} +7 -7
- package/dist/{chunk-2MR3MFQB.js → chunk-2VEOKUPP.js} +3 -3
- package/dist/chunk-2Z24E5W2.js +22 -0
- package/dist/chunk-2Z24E5W2.js.map +1 -0
- package/dist/{chunk-RHOZ5LLO.js → chunk-347WD2LE.js} +2 -2
- package/dist/{chunk-5S7Z5SHA.js → chunk-34RC5RT7.js} +2 -2
- package/dist/{chunk-KGWXHWAH.js → chunk-3QAH2S33.js} +3 -3
- package/dist/{chunk-37CTGERM.js → chunk-3WCASNQZ.js} +12 -1
- package/dist/chunk-3WCASNQZ.js.map +1 -0
- package/dist/{chunk-ZIDSD6VC.js → chunk-3Y224NYC.js} +3 -3
- package/dist/{chunk-RBQLJSJ7.js → chunk-44XZ75OQ.js} +46 -10
- package/dist/chunk-44XZ75OQ.js.map +1 -0
- package/dist/{chunk-VFSP73LP.js → chunk-45GF7Y3V.js} +2 -2
- package/dist/{chunk-7ICYQUOL.js → chunk-4BJQODZF.js} +2514 -1526
- package/dist/chunk-4BJQODZF.js.map +1 -0
- package/dist/{chunk-JMBVCAR4.js → chunk-57OWKFUQ.js} +17 -6
- package/dist/chunk-57OWKFUQ.js.map +1 -0
- package/dist/{chunk-OEHCMALU.js → chunk-5I4M26Q7.js} +5 -5
- package/dist/{chunk-2E6G7FCE.js → chunk-5Q7EVV4X.js} +7 -7
- package/dist/{chunk-LC7OODWZ.js → chunk-5SB7SC2G.js} +80 -49
- package/dist/chunk-5SB7SC2G.js.map +1 -0
- package/dist/{chunk-VZ5OJE4X.js → chunk-5VQJBH2G.js} +2 -2
- package/dist/{chunk-PUBTHW5O.js → chunk-6DRPPQEJ.js} +2 -2
- package/dist/{chunk-NWTGD4AN.js → chunk-6KIQT7RG.js} +10 -9
- package/dist/chunk-6KIQT7RG.js.map +1 -0
- package/dist/{chunk-4LEF6XWJ.js → chunk-6O22TZSB.js} +3 -3
- package/dist/{chunk-ZQ7UBUZ6.js → chunk-6QYST5XN.js} +6 -6
- package/dist/{chunk-W4PGTAS2.js → chunk-6WAFYNVT.js} +3 -3
- package/dist/chunk-6ZMAMSHS.js +20 -0
- package/dist/chunk-6ZMAMSHS.js.map +1 -0
- package/dist/{chunk-R5VAVVHP.js → chunk-72A4L5JJ.js} +2 -2
- package/dist/{chunk-X64YLC24.js → chunk-72VAXGEI.js} +5 -13
- package/dist/chunk-72VAXGEI.js.map +1 -0
- package/dist/{chunk-IKQTFQMI.js → chunk-755Q3DGF.js} +22 -3
- package/dist/chunk-755Q3DGF.js.map +1 -0
- package/dist/{chunk-F7AU34FC.js → chunk-76GLCM57.js} +160 -127
- package/dist/chunk-76GLCM57.js.map +1 -0
- package/dist/{chunk-D7FOKIY5.js → chunk-7AMFUATK.js} +12 -9
- package/dist/{chunk-D7FOKIY5.js.map → chunk-7AMFUATK.js.map} +1 -1
- package/dist/{chunk-BFVEEB7W.js → chunk-7ON2JW73.js} +57 -22
- package/dist/chunk-7ON2JW73.js.map +1 -0
- package/dist/chunk-7RNBVZZO.js +270 -0
- package/dist/chunk-7RNBVZZO.js.map +1 -0
- package/dist/{chunk-3FAMU5TX.js → chunk-A6USBZTO.js} +2 -2
- package/dist/{chunk-TXVD7PLT.js → chunk-A72SWTWW.js} +7 -7
- package/dist/{chunk-FC77VUX5.js → chunk-A7Q43EUZ.js} +2 -2
- package/dist/{chunk-UJBESW6X.js → chunk-AE7WMV4V.js} +7 -7
- package/dist/{chunk-J2HSAU72.js → chunk-AIK5W3IW.js} +29 -1
- package/dist/chunk-AIK5W3IW.js.map +1 -0
- package/dist/{chunk-OKUEZOGW.js → chunk-AITCS2RC.js} +2 -2
- package/dist/{chunk-OC35KQIN.js → chunk-AJ7QCSIS.js} +4 -4
- package/dist/{chunk-FNMFJWBY.js → chunk-ANEUPF6O.js} +5 -5
- package/dist/chunk-AREGMX2J.js +50 -0
- package/dist/chunk-AREGMX2J.js.map +1 -0
- package/dist/chunk-AVPXXV6J.js +448 -0
- package/dist/chunk-AVPXXV6J.js.map +1 -0
- package/dist/{chunk-2A3OXAP2.js → chunk-B7RWBZXW.js} +2 -2
- package/dist/{chunk-GWTFLF2P.js → chunk-BJMBJZ2Y.js} +59 -59
- package/dist/chunk-BJMBJZ2Y.js.map +1 -0
- package/dist/{chunk-N3JDIRBW.js → chunk-BLAKS3CP.js} +4 -4
- package/dist/{chunk-M7VGG3ID.js → chunk-BV5WMSIJ.js} +9 -9
- package/dist/{chunk-2BFLDH5F.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-UXKMMNJD.js → chunk-C23BYTJV.js} +6 -6
- package/dist/{chunk-JZHHREBL.js → chunk-C3AKM55W.js} +2 -2
- package/dist/{chunk-RP7YXA67.js → chunk-C5JF6EZ7.js} +2 -2
- package/dist/{chunk-FBNWOMCE.js → chunk-C6XBRYVD.js} +16 -15
- package/dist/chunk-C6XBRYVD.js.map +1 -0
- package/dist/{chunk-FTYDWKO6.js → chunk-CEN6DW6X.js} +12 -2
- package/dist/chunk-CEN6DW6X.js.map +1 -0
- package/dist/chunk-CGASUJVP.js +421 -0
- package/dist/chunk-CGASUJVP.js.map +1 -0
- package/dist/{chunk-DDGV7NAX.js → chunk-CQMEM5CC.js} +2 -2
- package/dist/{chunk-A7B4RMQG.js → chunk-CXZQOVIE.js} +12 -12
- package/dist/chunk-D3V3UMET.js +44 -0
- package/dist/chunk-D3V3UMET.js.map +1 -0
- package/dist/{chunk-7N2RUBAP.js → chunk-DDA47TES.js} +2 -2
- package/dist/{chunk-64SE4X5G.js → chunk-DEBHXHJR.js} +3 -3
- package/dist/{chunk-EHK6KZHK.js → chunk-DNHVPZOD.js} +2 -2
- package/dist/{chunk-437S3G37.js → chunk-DQEMWVMT.js} +2 -2
- package/dist/{chunk-LZZNTPLR.js → chunk-DX3XRGLH.js} +2 -2
- package/dist/chunk-EA2H5LML.js +72 -0
- package/dist/chunk-EA2H5LML.js.map +1 -0
- package/dist/{chunk-IFJ23BHU.js → chunk-EEC7UJPX.js} +112 -106
- package/dist/chunk-EEC7UJPX.js.map +1 -0
- package/dist/{chunk-KSNVDPDF.js → chunk-EKBNDKDY.js} +21 -20
- package/dist/chunk-EKBNDKDY.js.map +1 -0
- package/dist/{chunk-YF6FMLBT.js → chunk-EQWEIIKQ.js} +64 -34
- package/dist/chunk-EQWEIIKQ.js.map +1 -0
- package/dist/{chunk-7MW3CVLD.js → chunk-ES36HTSC.js} +4 -4
- package/dist/{chunk-TN7THW5U.js → chunk-ET356KSB.js} +2 -2
- package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
- package/dist/{chunk-7LFXDGLH.js → chunk-F7GAIWFA.js} +20 -20
- package/dist/{chunk-IKSELOIV.js → chunk-FFPJINJE.js} +7 -7
- package/dist/chunk-FMLKOL2Z.js +636 -0
- package/dist/chunk-FMLKOL2Z.js.map +1 -0
- package/dist/chunk-FQC3DHH2.js +20 -0
- package/dist/chunk-FQC3DHH2.js.map +1 -0
- package/dist/{chunk-V53GJUSL.js → chunk-FUTF72MJ.js} +15 -15
- package/dist/chunk-GCASGYIO.js +71 -0
- package/dist/chunk-GCASGYIO.js.map +1 -0
- package/dist/{chunk-5UNWK7KU.js → chunk-GFPZS3F5.js} +8 -8
- package/dist/{chunk-BCDKBDSY.js → chunk-GNVZQ5JN.js} +99 -41
- package/dist/chunk-GNVZQ5JN.js.map +1 -0
- package/dist/{chunk-G6NKALRN.js → chunk-H4WG3UQZ.js} +2 -2
- package/dist/{chunk-HLTAPHZZ.js → chunk-HNZKVLAN.js} +2 -2
- package/dist/{chunk-5EZXHU36.js → chunk-HYQJQGD3.js} +2 -2
- package/dist/{chunk-ANADNYWK.js → chunk-IDZFBSHN.js} +8 -6
- package/dist/{chunk-ANADNYWK.js.map → chunk-IDZFBSHN.js.map} +1 -1
- package/dist/{chunk-XVLEGMJI.js → chunk-IFH6LWTO.js} +50 -8
- package/dist/chunk-IFH6LWTO.js.map +1 -0
- package/dist/{chunk-RULE4VG5.js → chunk-ILGC6JH6.js} +21 -6
- package/dist/chunk-ILGC6JH6.js.map +1 -0
- package/dist/chunk-IUM3VSHI.js +113 -0
- package/dist/chunk-IUM3VSHI.js.map +1 -0
- package/dist/{chunk-ND5M64JJ.js → chunk-IYNGIMVG.js} +101 -91
- package/dist/chunk-IYNGIMVG.js.map +1 -0
- package/dist/{chunk-TRWPCR6P.js → chunk-JECBQBEX.js} +3 -3
- package/dist/{chunk-HG32URJJ.js → chunk-JYIFGGEM.js} +2 -2
- package/dist/{chunk-VA4WSW54.js → chunk-JYIJNNN3.js} +3 -3
- package/dist/{chunk-L5HJQC36.js → chunk-K2TDK7GG.js} +3 -3
- package/dist/{chunk-MKDRQAA3.js → chunk-KAVBJSBQ.js} +4 -4
- package/dist/{chunk-EEARRVZ2.js → chunk-KF5EUVKQ.js} +16 -6
- package/dist/chunk-KF5EUVKQ.js.map +1 -0
- package/dist/chunk-KFZY2OFH.js +42 -0
- package/dist/chunk-KFZY2OFH.js.map +1 -0
- package/dist/{chunk-4OKLXWDZ.js → chunk-KNB7IBBU.js} +2 -2
- package/dist/{chunk-QLULYKWZ.js → chunk-KSXJOC4F.js} +2 -2
- package/dist/{chunk-OBMR4VIX.js → chunk-L2DPF4DF.js} +186 -15
- package/dist/chunk-L2DPF4DF.js.map +1 -0
- package/dist/{chunk-JI5AVXYO.js → chunk-LEPOP46W.js} +6 -6
- package/dist/{chunk-O7BBFJLP.js → chunk-LTAVSOZW.js} +2 -2
- package/dist/{chunk-E3VODCC3.js → chunk-LUDXM7MD.js} +14 -2
- package/dist/{chunk-E3VODCC3.js.map → chunk-LUDXM7MD.js.map} +1 -1
- package/dist/{chunk-2IZAGAJR.js → chunk-LULR4IUW.js} +3 -3
- package/dist/{chunk-NUWYOKS6.js → chunk-MC5Q3J7S.js} +398 -7
- package/dist/chunk-MC5Q3J7S.js.map +1 -0
- package/dist/{chunk-WMWVO45V.js → chunk-MC6XO7T4.js} +2 -2
- package/dist/chunk-MKQBXQKU.js +107 -0
- package/dist/chunk-MKQBXQKU.js.map +1 -0
- package/dist/{chunk-7PND4PUC.js → chunk-MMGGVZ4Q.js} +29 -9
- package/dist/{chunk-7PND4PUC.js.map → chunk-MMGGVZ4Q.js.map} +1 -1
- package/dist/{chunk-D6RIFG4O.js → chunk-MNB5RMAY.js} +2 -2
- package/dist/{chunk-67ZCJLJY.js → chunk-MYFQ3ED4.js} +8 -8
- package/dist/{chunk-V3UE5I5F.js → chunk-MYVPLJOO.js} +2 -2
- package/dist/chunk-NINSR6LX.js +83 -0
- package/dist/chunk-NINSR6LX.js.map +1 -0
- package/dist/{chunk-MTWKDOVO.js → chunk-NLE6TSLG.js} +2 -2
- package/dist/{chunk-DBRYEIGY.js → chunk-OJP3N7UK.js} +2 -2
- package/dist/{chunk-AD6AMF2N.js → chunk-OQJIB32H.js} +28 -23
- package/dist/chunk-OQJIB32H.js.map +1 -0
- package/dist/{chunk-SMX5267P.js → chunk-OZKOPQCM.js} +2 -2
- package/dist/{chunk-JCK7V6SN.js → chunk-P65YJEEL.js} +2 -2
- package/dist/{chunk-MTR7BZQN.js → chunk-PBGWYM3H.js} +3 -3
- package/dist/chunk-PIG4WJFQ.js +87 -0
- package/dist/chunk-PIG4WJFQ.js.map +1 -0
- package/dist/chunk-PQVCH2AE.js +76 -0
- package/dist/chunk-PQVCH2AE.js.map +1 -0
- package/dist/{chunk-AXTXN4T6.js → chunk-PWFCHOB3.js} +2 -2
- package/dist/{chunk-FDPZVY6D.js → chunk-QFN4U7AG.js} +2 -2
- package/dist/{chunk-K2ZLHESQ.js → chunk-QIEUU4UK.js} +2 -2
- package/dist/{chunk-AHLPZ2SF.js → chunk-QJAQNXWI.js} +44 -6
- package/dist/chunk-QJAQNXWI.js.map +1 -0
- package/dist/{chunk-3D6AFGQR.js → chunk-QVT3E4CE.js} +7 -7
- package/dist/{chunk-VYOFVVNK.js → chunk-R26ZMXR2.js} +24 -24
- package/dist/{chunk-VYOFVVNK.js.map → chunk-R26ZMXR2.js.map} +1 -1
- package/dist/chunk-R3DJVOSM.js +34 -0
- package/dist/chunk-R3DJVOSM.js.map +1 -0
- package/dist/{chunk-SFQ6QNL7.js → chunk-R6YJI3HE.js} +2 -1
- package/dist/{chunk-5CJVLG3H.js → chunk-RFDD3B7W.js} +5 -5
- package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/chunk-ROI7BK7H.js +88 -0
- package/dist/chunk-ROI7BK7H.js.map +1 -0
- package/dist/{chunk-UTRJFDP2.js → chunk-S2BBISHU.js} +4 -4
- package/dist/{chunk-IALLX7EE.js → chunk-S2FSBU4H.js} +3 -3
- package/dist/{chunk-BFPETA3S.js → chunk-SCCO46KZ.js} +3 -2
- package/dist/chunk-SCCO46KZ.js.map +1 -0
- package/dist/chunk-SICXL4MK.js +165 -0
- package/dist/chunk-SICXL4MK.js.map +1 -0
- package/dist/chunk-SK7AMF2J.js +168 -0
- package/dist/chunk-SK7AMF2J.js.map +1 -0
- package/dist/{chunk-GMSDQUCR.js → chunk-TDTXKOAJ.js} +6475 -5748
- package/dist/chunk-TDTXKOAJ.js.map +1 -0
- package/dist/{chunk-KSBEEMQF.js → chunk-TG6IHVE2.js} +151 -6
- package/dist/chunk-TG6IHVE2.js.map +1 -0
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-PK5XBDA6.js → chunk-U3ZAVRP3.js} +2 -2
- package/dist/{chunk-ODPLEWB6.js → chunk-UFGFMWAD.js} +47 -17
- package/dist/chunk-UFGFMWAD.js.map +1 -0
- package/dist/{chunk-4KJLYTLS.js → chunk-V57NLO5P.js} +2 -2
- package/dist/{chunk-FLVL4L3L.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-7XGSIUP5.js → chunk-W4FBGYGK.js} +1 -1
- package/dist/{chunk-TXLGHDHS.js → chunk-W4XJFLAL.js} +53 -32
- package/dist/chunk-W4XJFLAL.js.map +1 -0
- package/dist/{chunk-6SXVCD7W.js → chunk-W7IGLX4G.js} +2 -2
- package/dist/{chunk-KQDNAXOM.js → chunk-WG5HSQ4P.js} +19 -6
- package/dist/chunk-WG5HSQ4P.js.map +1 -0
- package/dist/{chunk-LTJAMRGI.js → chunk-WL5EBRDH.js} +17 -3
- package/dist/chunk-WL5EBRDH.js.map +1 -0
- package/dist/{chunk-KAWTOYAW.js → chunk-WLZYGLJ4.js} +2 -2
- package/dist/{chunk-W5NKDU24.js → chunk-WON4APQY.js} +4 -4
- package/dist/{chunk-NKCPUHCI.js → chunk-WZFAPHIK.js} +6 -6
- package/dist/{chunk-KQPJLK3X.js → chunk-XL24QQ63.js} +2 -2
- package/dist/{chunk-X47LWMKA.js → chunk-XMMESCPD.js} +26 -1
- package/dist/chunk-XMMESCPD.js.map +1 -0
- package/dist/{chunk-4B4MUS5D.js → chunk-YROFNEG5.js} +7 -7
- package/dist/{chunk-WU46YPY6.js → chunk-YV32N67O.js} +1 -1
- package/dist/chunk-YV32N67O.js.map +1 -0
- package/dist/{chunk-B3F4CWQR.js → chunk-YVKF3HEW.js} +1 -1
- package/dist/chunk-YVKF3HEW.js.map +1 -0
- package/dist/{chunk-VRAD2FGO.js → chunk-Z54EM5YZ.js} +12 -12
- package/dist/{chunk-2VN4JAX7.js → chunk-ZOKZIR5K.js} +95 -33
- package/dist/chunk-ZOKZIR5K.js.map +1 -0
- package/dist/{cli-_Y2Bmt6A.d.ts → cli-C_pqqTCw.d.ts} +28 -12
- package/dist/cli.d.ts +16 -9
- package/dist/cli.js +145 -130
- package/dist/compounding/engine.d.ts +5 -2
- package/dist/compounding/engine.js +39 -29
- package/dist/compounding/preference-consolidator.d.ts +3 -1
- package/dist/compounding/preference-consolidator.js +1 -1
- package/dist/compression-optimizer.d.ts +3 -1
- package/dist/config-qmd.d.ts +8 -0
- package/dist/config-qmd.js +20 -0
- package/dist/config-qmd.js.map +1 -0
- package/dist/config.d.ts +3 -1
- package/dist/config.js +15 -10
- package/dist/connectors/codex-materialize-runner.d.ts +3 -1
- package/dist/connectors/codex-materialize-runner.js +39 -29
- package/dist/connectors/codex-materialize.d.ts +3 -1
- package/dist/connectors/codex-materialize.js +2 -2
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.js +44 -35
- package/dist/consolidation-provenance-check.d.ts +5 -2
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +5 -2
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.d.ts +5 -2
- package/dist/contradiction/index.js +10 -4
- package/dist/{contradiction-scan-J57T5QV7.js → contradiction-scan-RJBABNRH.js} +4 -4
- package/dist/contradiction-scan-RJBABNRH.js.map +1 -0
- package/dist/conversation-index/backend.d.ts +3 -1
- package/dist/conversation-index/backend.js +5 -5
- package/dist/conversation-index/chunker.d.ts +3 -1
- package/dist/conversation-index/cleanup.js +2 -2
- package/dist/conversation-index/faiss-adapter.d.ts +3 -1
- package/dist/conversation-index/faiss-adapter.js +2 -2
- package/dist/conversation-index/indexer.d.ts +3 -1
- package/dist/conversation-index/indexer.js +2 -2
- package/dist/conversation-index/search.d.ts +3 -1
- package/dist/conversation-index/search.js +2 -2
- package/dist/cross-namespace-budget.d.ts +45 -1
- package/dist/cross-namespace-budget.js +5 -3
- package/dist/dashboard-runtime.js +2 -2
- package/dist/day-summary.d.ts +3 -1
- package/dist/day-summary.js +3 -3
- package/dist/delinearize.d.ts +3 -1
- package/dist/direct-answer-wiring.d.ts +3 -1
- package/dist/direct-answer.d.ts +3 -1
- package/dist/{dreams-ledger-6UODQOX6.js → dreams-ledger-567VKVOU.js} +4 -2
- package/dist/dreams-ledger-567VKVOU.js.map +1 -0
- package/dist/embedding-fallback.d.ts +3 -1
- package/dist/embedding-fallback.js +3 -3
- package/dist/enrichment/index.d.ts +3 -1
- package/dist/entity-retrieval.d.ts +5 -2
- package/dist/entity-retrieval.js +38 -29
- package/dist/entity-schema.d.ts +3 -1
- package/dist/explicit-capture.d.ts +13 -8
- package/dist/explicit-capture.js +7 -3
- package/dist/extraction-faithfulness.d.ts +3 -1
- package/dist/extraction-faithfulness.js +5 -5
- package/dist/extraction-judge-telemetry.d.ts +3 -1
- package/dist/extraction-judge-telemetry.js +2 -2
- package/dist/extraction-judge-training.d.ts +3 -1
- package/dist/extraction-judge-training.js +2 -2
- package/dist/extraction-judge.d.ts +3 -1
- package/dist/extraction-judge.js +5 -5
- package/dist/extraction.d.ts +3 -1
- package/dist/extraction.js +13 -12
- package/dist/faithfulness-config.js +3 -2
- package/dist/fallback-llm.d.ts +3 -1
- package/dist/fallback-llm.js +4 -4
- package/dist/{first-start-migration-TI67YMLG.js → first-start-migration-CSRHCJIQ.js} +2 -2
- package/dist/{forget-CQCLB5LB.js → forget-HRPLVB3W.js} +5 -5
- package/dist/graph-dashboard-diff.d.ts +3 -1
- package/dist/graph-dashboard-key.d.ts +3 -1
- package/dist/graph-dashboard-parser.d.ts +3 -1
- package/dist/{graph-edge-decay-FO7AM4UR.js → graph-edge-decay-Z6ENALU2.js} +3 -3
- package/dist/graph-edge-decay-Z6ENALU2.js.map +1 -0
- package/dist/graph-edge-reinforcement.d.ts +3 -1
- package/dist/graph-snapshot.d.ts +3 -1
- package/dist/graph-snapshot.js +2 -2
- package/dist/graph.d.ts +57 -10
- package/dist/graph.js +1 -1
- package/dist/identity-continuity.d.ts +1 -2
- package/dist/importance.d.ts +3 -1
- package/dist/importers/index.d.ts +3 -1
- package/dist/in-flight-reads.d.ts +3 -1
- package/dist/index.d.ts +101 -92
- package/dist/index.js +290 -242
- package/dist/intent.d.ts +3 -1
- package/dist/lcm/archive.js +2 -2
- package/dist/lcm/engine.d.ts +3 -1
- package/dist/lcm/engine.js +6 -6
- package/dist/lcm/index.d.ts +3 -1
- package/dist/lcm/index.js +13 -13
- package/dist/lcm/schema.js +2 -2
- package/dist/lcm/summarizer.js +3 -3
- package/dist/lcm/tools.d.ts +3 -1
- package/dist/lifecycle.d.ts +3 -1
- package/dist/live-connectors-runner.d.ts +3 -1
- package/dist/local-llm.d.ts +5 -2
- package/dist/local-llm.js +3 -3
- package/dist/local-model-endpoint.d.ts +3 -1
- package/dist/logger.d.ts +3 -1
- package/dist/logger.js +7 -3
- package/dist/maintenance/archive-observations.js +2 -2
- package/dist/maintenance/memory-governance.d.ts +3 -1
- package/dist/maintenance/memory-governance.js +38 -28
- package/dist/maintenance/migrate-observations.js +3 -3
- package/dist/maintenance/observation-ledger-utils.js +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +102 -1
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +40 -28
- package/dist/maintenance/rebuild-memory-projection.js +41 -31
- package/dist/maintenance/rebuild-observations.js +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +22 -15
- package/dist/memory-action-policy.d.ts +3 -1
- package/dist/memory-cache.d.ts +46 -2
- package/dist/memory-cache.js +7 -1
- package/dist/memory-corpus-version.js +2 -2
- package/dist/memory-lifecycle-ledger-utils.d.ts +25 -2
- package/dist/memory-lifecycle-ledger-utils.js +11 -1
- package/dist/memory-projection-store.d.ts +3 -1
- package/dist/memory-projection-store.js +2 -2
- package/dist/memory-provenance.d.ts +3 -1
- package/dist/memory-worth-outcomes.d.ts +5 -2
- package/dist/model-registry.js +2 -2
- package/dist/models-json.d.ts +3 -1
- package/dist/models-json.js +2 -2
- package/dist/namespaces/migrate.d.ts +6 -3
- package/dist/namespaces/migrate.js +54 -45
- package/dist/namespaces/principal.d.ts +27 -2
- package/dist/namespaces/principal.js +6 -2
- package/dist/namespaces/search.d.ts +16 -2
- package/dist/namespaces/search.js +25 -21
- package/dist/namespaces/storage.d.ts +24 -3
- package/dist/namespaces/storage.js +38 -30
- package/dist/native-knowledge.d.ts +3 -1
- package/dist/native-knowledge.js +2 -2
- package/dist/negative.js +2 -2
- package/dist/offline-sync-exclude-globs.d.ts +13 -0
- package/dist/offline-sync-exclude-globs.js +10 -0
- package/dist/offline-sync-exclude-globs.js.map +1 -0
- package/dist/offline-sync-impression-drain.d.ts +78 -0
- package/dist/offline-sync-impression-drain.js +37 -0
- package/dist/offline-sync-impression-drain.js.map +1 -0
- package/dist/offline-sync.js +4 -2
- package/dist/operator-toolkit.d.ts +5 -2
- package/dist/operator-toolkit.js +73 -58
- package/dist/orchestration/compression-guideline-coordinator.d.ts +5 -2
- package/dist/orchestration/compression-guideline-coordinator.js +3 -3
- package/dist/orchestration/maintenance.d.ts +121 -2
- package/dist/orchestration/maintenance.js +47 -34
- package/dist/{orchestrator-BbZ_dQSU.d.ts → orchestrator-CQJ8U7En.d.ts} +85 -79
- package/dist/orchestrator.d.ts +13 -8
- package/dist/orchestrator.js +197 -180
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +3 -1
- package/dist/{pipeline-FRMDb1fn.d.ts → pipeline-Cn-kvYeV.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +3 -1
- package/dist/prioritized-embed.d.ts +19 -0
- package/dist/prioritized-embed.js +8 -0
- package/dist/prioritized-embed.js.map +1 -0
- package/dist/proactive-contention.d.ts +28 -0
- package/dist/proactive-contention.js +8 -0
- package/dist/proactive-contention.js.map +1 -0
- package/dist/profiling.js +2 -2
- package/dist/provenance.d.ts +3 -1
- package/dist/provenance.js +3 -2
- package/dist/{purge-NDWV6WYD.js → purge-IRF47ZTX.js} +3 -3
- package/dist/{qmd-xJRrHFbA.d.ts → qmd-oh9VXz1d.d.ts} +11 -1
- package/dist/qmd-preflight.d.ts +5 -2
- package/dist/qmd-recall-cache.d.ts +3 -1
- package/dist/qmd-status.d.ts +57 -0
- package/dist/qmd-status.js +18 -0
- package/dist/qmd-status.js.map +1 -0
- package/dist/qmd.d.ts +5 -2
- package/dist/qmd.js +8 -4
- package/dist/recall-concurrency-config.d.ts +16 -0
- package/dist/recall-concurrency-config.js +10 -0
- package/dist/recall-concurrency-config.js.map +1 -0
- package/dist/recall-disclosure-escalation.d.ts +3 -1
- package/dist/recall-explain-renderer.d.ts +4 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +26 -0
- package/dist/recall-memory-map.js +18 -0
- package/dist/recall-memory-map.js.map +1 -0
- package/dist/recall-planner-llm.d.ts +3 -1
- package/dist/recall-planner-llm.js +4 -4
- package/dist/recall-qos.js +2 -2
- package/dist/recall-state.d.ts +163 -2
- package/dist/recall-state.js +6 -3
- package/dist/recall-tag-filter.d.ts +3 -1
- package/dist/recall-timings.d.ts +11 -2
- package/dist/recall-timings.js +3 -1
- package/dist/recall-xray-cli.d.ts +3 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +3 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +3 -1
- package/dist/recall-xray.js +2 -2
- package/dist/relevance.js +3 -3
- package/dist/replay/normalizers/chatgpt.d.ts +3 -1
- package/dist/replay/normalizers/claude.d.ts +3 -1
- package/dist/replay/normalizers/openclaw.d.ts +3 -1
- package/dist/replay/normalizers/shared.d.ts +3 -1
- package/dist/replay/runner.d.ts +3 -1
- package/dist/replay/types.d.ts +3 -1
- package/dist/rerank.d.ts +8 -1
- package/dist/rerank.js +3 -1
- package/dist/resolution-3K27T4VO.js +18 -0
- package/dist/resolution-3K27T4VO.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +3 -1
- package/dist/resolve-provider-secret.js +2 -2
- package/dist/resume-bundles.js +19 -14
- package/dist/retrieval-agents.d.ts +19 -16
- package/dist/retrieval-agents.js +3 -3
- package/dist/retrieval-tiers.d.ts +3 -1
- package/dist/routing/engine.d.ts +3 -1
- package/dist/routing/store.d.ts +3 -1
- package/dist/routing/store.js +2 -2
- package/dist/salvage-envelope.d.ts +18 -0
- package/dist/salvage-envelope.js +15 -0
- package/dist/salvage-envelope.js.map +1 -0
- package/dist/schemas.d.ts +24 -24
- package/dist/scope-profiles-EpJG7yKP.d.ts +30 -0
- package/dist/search/document-scanner.js +3 -2
- package/dist/search/embed-helper.d.ts +3 -1
- package/dist/search/embed-helper.js +3 -3
- package/dist/search/factory.d.ts +3 -1
- package/dist/search/factory.js +19 -17
- package/dist/search/index.d.ts +3 -1
- package/dist/search/index.js +23 -21
- package/dist/search/lancedb-backend.d.ts +3 -1
- package/dist/search/lancedb-backend.js +6 -5
- package/dist/search/meilisearch-backend.d.ts +3 -1
- package/dist/search/meilisearch-backend.js +6 -5
- package/dist/search/noop-backend.d.ts +3 -1
- package/dist/search/orama-backend.d.ts +3 -1
- package/dist/search/orama-backend.js +6 -5
- package/dist/search/port.d.ts +27 -2
- package/dist/search/port.js +1 -1
- package/dist/search/remote-backend.d.ts +3 -1
- package/dist/search/remote-backend.js +3 -3
- package/dist/secure-store/index.d.ts +12 -1
- package/dist/secure-store/index.js +6 -3
- package/dist/{semantic-consolidation-fvdZRa5Z.d.ts → semantic-consolidation-DILZEQq3.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +4 -2
- package/dist/semantic-consolidation.js +41 -32
- package/dist/semantic-rule-promotion.js +37 -27
- package/dist/semantic-rule-verifier.d.ts +3 -1
- package/dist/semantic-rule-verifier.js +38 -28
- package/dist/session-observer-bands.d.ts +3 -1
- package/dist/session-observer-state.d.ts +3 -1
- package/dist/session-observer-state.js +2 -2
- package/dist/session-transcript-migration.js +2 -2
- package/dist/shared-context/manager.d.ts +3 -1
- package/dist/shared-context/manager.js +3 -3
- package/dist/signal.d.ts +3 -1
- package/dist/{storage-CrvzaM9C.d.ts → storage-NIyKYD8g.d.ts} +505 -110
- package/dist/storage-guards.js +2 -2
- package/dist/storage.d.ts +6 -3
- package/dist/storage.js +41 -29
- package/dist/structured-attributes.d.ts +23 -1
- package/dist/structured-attributes.js +7 -1
- package/dist/summarizer.d.ts +3 -1
- package/dist/summarizer.js +11 -11
- package/dist/summary-snapshot.d.ts +3 -1
- package/dist/summary-snapshot.js +2 -2
- package/dist/temporal-index-batch.d.ts +1 -0
- package/dist/temporal-index-batch.js +10 -0
- package/dist/temporal-index-batch.js.map +1 -0
- package/dist/temporal-index-compat.d.ts +279 -1
- package/dist/temporal-index-compat.js +1 -1
- package/dist/temporal-index.d.ts +1 -225
- package/dist/temporal-index.js +35 -3
- package/dist/temporal-supersession.d.ts +5 -2
- package/dist/temporal-supersession.js +2 -2
- package/dist/temporal-timeline-recall.d.ts +3 -1
- package/dist/temporal-validity.d.ts +3 -1
- package/dist/threading.d.ts +3 -1
- package/dist/threading.js +2 -2
- package/dist/tier-migration.d.ts +5 -2
- package/dist/tier-routing.d.ts +3 -1
- package/dist/{tier-stats-KV7IWCJR.js → tier-stats-QEJSPFV2.js} +2 -2
- package/dist/tokens.js +3 -3
- package/dist/topics.d.ts +3 -1
- package/dist/transcript.d.ts +3 -1
- package/dist/transcript.js +2 -2
- package/dist/transfer/backup.js +3 -3
- package/dist/transfer/capsule-export.js +3 -3
- package/dist/transfer/capsule-import.js +6 -6
- package/dist/transfer/types.d.ts +24 -24
- package/dist/trust-score-stage.d.ts +75 -38
- package/dist/trust-score-stage.js +11 -3
- package/dist/trust-score.d.ts +3 -1
- package/dist/{types-Bl4BWDM8.d.ts → types-D_fG2ix8.d.ts} +49 -63
- package/dist/types-continuity.d.ts +52 -0
- package/dist/types-continuity.js +1 -0
- package/dist/types-continuity.js.map +1 -0
- package/dist/types.d.ts +3 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +3 -1
- package/dist/utils/serialize-mutations.d.ts +31 -2
- package/dist/utils/serialize-mutations.js +1 -1
- package/dist/verified-recall.js +39 -29
- package/dist/write-envelope.d.ts +282 -0
- package/dist/write-envelope.js +35 -0
- package/dist/write-envelope.js.map +1 -0
- package/dist/write-quarantine.d.ts +79 -0
- package/dist/write-quarantine.js +11 -0
- package/dist/write-quarantine.js.map +1 -0
- package/dist/write-rate-limiter.d.ts +45 -0
- package/dist/write-rate-limiter.js +9 -0
- package/dist/write-rate-limiter.js.map +1 -0
- package/package.json +37 -2
- package/src/access-admin-ops-surface.ts +17 -7
- package/src/access-boundary.test.ts +28 -0
- package/src/access-boundary.ts +31 -2
- package/src/access-citation.test.ts +72 -0
- package/src/access-citation.ts +139 -0
- package/src/access-errors.ts +21 -0
- package/src/access-fingerprint-parity.test.ts +211 -0
- package/src/access-http-cancellation.test.ts +59 -21
- package/src/access-http.test.ts +90 -0
- package/src/access-http.ts +79 -79
- package/src/access-mcp-cancellation.test.ts +16 -7
- package/src/access-memory-search-fanout.test.ts +220 -0
- package/src/access-memory-search-fanout.ts +168 -0
- package/src/access-observe-quarantine.test.ts +120 -0
- package/src/access-observe-write-surface.ts +130 -11
- package/src/access-operations-batch.ts +2 -0
- package/src/access-recall-concurrency.ts +773 -0
- package/src/access-recall-response.ts +307 -0
- package/src/access-recall-surface.ts +100 -252
- package/src/access-service-coding-write.test.ts +22 -4
- package/src/access-service-health.test.ts +49 -0
- package/src/access-service-namespace.test.ts +486 -8
- package/src/access-service-observe-scope.test.ts +4 -0
- package/src/access-service-recall-concurrency.test.ts +1990 -0
- package/src/access-service.ts +182 -175
- package/src/access-surface-catalog.ts +1 -0
- package/src/access-token-capabilities.ts +16 -9
- package/src/active-recall.test.ts +35 -0
- package/src/active-recall.ts +7 -0
- package/src/bounded-jsonl-state.ts +93 -0
- package/src/buffer-session.test.ts +422 -5
- package/src/buffer-surprise-trigger.test.ts +41 -0
- package/src/buffer.ts +218 -3
- package/src/capabilities-cluster-b.test.ts +1 -0
- package/src/capabilities.ts +5 -6
- package/src/cli.ts +21 -22
- package/src/coding/architecture-surfaces.test.ts +6 -3
- package/src/coding/architecture-surfaces.ts +36 -25
- package/src/coding/decision-surfaces.ts +42 -34
- package/src/compounding/engine.test.ts +5 -1
- package/src/compounding/engine.ts +7 -7
- package/src/config-qmd.ts +89 -0
- package/src/config.test.ts +136 -0
- package/src/config.ts +122 -118
- package/src/connector-provenance-lifecycle.test.ts +4 -4
- package/src/connectors/coerce.test.ts +131 -0
- package/src/connectors/coerce.ts +80 -7
- package/src/contradiction/contradiction.test.ts +10 -6
- package/src/contradiction/resolution.ts +17 -4
- package/src/correction/correction-access-wiring.ts +62 -18
- package/src/cross-namespace-budget.test.ts +35 -0
- package/src/cross-namespace-budget.ts +86 -19
- package/src/explicit-capture.ts +54 -17
- package/src/extraction.ts +2 -3
- package/src/faithfulness-graph-guard.test.ts +16 -69
- package/src/graph-recall.test.ts +31 -0
- package/src/graph.test.ts +137 -1
- package/src/graph.ts +274 -17
- package/src/index.ts +22 -2
- package/src/local-llm.ts +4 -6
- package/src/logger.ts +16 -0
- package/src/maintenance/dreams-ledger.ts +100 -49
- package/src/maintenance/rebuild-memory-lifecycle-ledger-cli.ts +77 -0
- package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +373 -9
- package/src/memory-cache.ts +70 -0
- package/src/memory-lifecycle-ledger-utils.ts +51 -5
- package/src/namespaces/principal.test.ts +37 -1
- package/src/namespaces/principal.ts +48 -0
- package/src/namespaces/search.test.ts +79 -5
- package/src/namespaces/search.ts +59 -6
- package/src/namespaces/storage.ts +45 -1
- package/src/offline-sync-exclude-globs.ts +58 -0
- package/src/offline-sync-impression-drain.test.ts +316 -0
- package/src/offline-sync-impression-drain.ts +260 -0
- package/src/offline-sync.test.ts +32 -5
- package/src/offline-sync.ts +1 -14
- package/src/operator-toolkit.ts +1 -1
- package/src/orchestration/batch-deindex-flush.test.ts +146 -0
- package/src/orchestration/consolidation-run.ts +96 -85
- package/src/orchestration/extraction-envelope.ts +94 -0
- package/src/orchestration/extraction-persist-promotion.ts +134 -0
- package/src/orchestration/extraction-persist.ts +325 -260
- package/src/orchestration/extraction-run.test.ts +1 -1
- package/src/orchestration/extraction-run.ts +2 -2
- package/src/orchestration/graph-recall-coordinator.ts +18 -7
- package/src/orchestration/lifecycle-policy-coordinator.ts +63 -48
- package/src/orchestration/maintenance.test.ts +2103 -3
- package/src/orchestration/maintenance.ts +581 -2
- package/src/orchestration/namespace-read-fanout.ts +14 -8
- package/src/orchestration/orchestrator-helpers.ts +8 -1
- package/src/orchestration/orchestrator-init.ts +22 -6
- package/src/orchestration/orchestrator-namespace-scope.ts +71 -0
- package/src/orchestration/persistence-index.ts +64 -9
- package/src/orchestration/qmd-result-resolver.ts +27 -0
- package/src/orchestration/recall-entry.ts +34 -19
- package/src/orchestration/recall-internal.ts +207 -79
- package/src/orchestration/recall-rerank-coordinator.ts +229 -82
- package/src/orchestration/recall-result-formatter.ts +76 -20
- package/src/orchestration/recall-search-pipeline.test.ts +70 -0
- package/src/orchestration/recall-search-pipeline.ts +102 -129
- package/src/orchestration/recall-section-coordinator.ts +315 -85
- package/src/orchestration/semantic-consolidation-coordinator.ts +69 -37
- package/src/orchestration/session-context.ts +21 -0
- package/src/orchestration/workspace-ops.test.ts +348 -0
- package/src/orchestration/workspace-ops.ts +172 -34
- package/src/orchestrator-chunked-hash-durability.test.ts +126 -0
- package/src/orchestrator-connector-dedup.test.ts +1061 -40
- package/src/orchestrator-flush.test.ts +155 -39
- package/src/orchestrator-nonchunked-hash-durability.test.ts +121 -0
- package/src/orchestrator-source-attribution.test.ts +9 -9
- package/src/orchestrator.ts +166 -150
- package/src/prioritized-embed.ts +123 -0
- package/src/proactive-contention.test.ts +80 -0
- package/src/proactive-contention.ts +39 -0
- package/src/procedural/procedure-miner.test.ts +19 -14
- package/src/procedural/procedure-miner.ts +44 -13
- package/src/qmd-client.test.ts +111 -1
- package/src/qmd-status.ts +186 -0
- package/src/qmd.test.ts +22 -0
- package/src/qmd.ts +60 -48
- package/src/recall-budget-config.test.ts +30 -0
- package/src/recall-cold-deadline.test.ts +149 -0
- package/src/recall-concurrency-config.ts +28 -0
- package/src/recall-memory-map.ts +74 -0
- package/src/recall-rerank-coordinator.test.ts +508 -0
- package/src/recall-state.test.ts +825 -1
- package/src/recall-state.ts +406 -7
- package/src/recall-timings-access.test.ts +41 -0
- package/src/recall-timings.ts +16 -0
- package/src/relay/mission-access.test.ts +5 -5
- package/src/rerank.ts +22 -0
- package/src/retrieval-agents.test.ts +79 -0
- package/src/retrieval-agents.ts +71 -19
- package/src/salvage-envelope.ts +28 -0
- package/src/scopes/scope-plan.test.ts +42 -0
- package/src/scopes/scope-plan.ts +45 -0
- package/src/search/port.ts +24 -0
- package/src/secure-store/index.ts +1 -0
- package/src/secure-store/secure-fs.ts +48 -0
- package/src/secure-store/secure-store.test.ts +40 -0
- package/src/semantic-rule-promotion.ts +13 -4
- package/src/storage/content-hash-index.ts +655 -0
- package/src/storage/entity-timeline.ts +473 -0
- package/src/storage/memory-lifecycle-ledger-access.ts +603 -0
- package/src/storage/secure-line-reader.test.ts +197 -0
- package/src/storage/secure-line-reader.ts +181 -3
- package/src/storage-append-header-sniff.test.ts +195 -0
- package/src/storage-behavior-signals-cache.test.ts +237 -0
- package/src/storage-contract/cache-coherence.test.ts +96 -1
- package/src/storage-contract/content-hash.test.ts +47 -2
- package/src/storage-fact-hash-index-defer.test.ts +1200 -0
- package/src/storage-memory-lifecycle-ledger.test.ts +1146 -3
- package/src/storage.ts +942 -903
- package/src/structured-attributes.ts +52 -0
- package/src/temporal-index-batch.ts +112 -0
- package/src/temporal-index.test.ts +193 -0
- package/src/temporal-index.ts +49 -53
- package/src/testing/lifecycle-matrix.test.ts +212 -0
- package/src/testing/lifecycle-matrix.ts +271 -0
- package/src/testing/orchestrator-lite.ts +236 -0
- package/src/testing/subjects/dreams-ledger.test.ts +67 -0
- package/src/testing/subjects/extraction-lifecycle.test.ts +442 -0
- package/src/testing/subjects/lifecycle-ledger.test.ts +93 -0
- package/src/testing/subjects/recall-budget.test.ts +461 -0
- package/src/testing/subjects/serialized-write-chain.test.ts +224 -0
- package/src/trust-score-stage.test.ts +154 -0
- package/src/trust-score-stage.ts +216 -53
- package/src/types-continuity.ts +57 -0
- package/src/types.ts +66 -77
- package/src/utils/path-containment.test.ts +75 -0
- package/src/utils/path-containment.ts +76 -0
- package/src/utils/serialize-mutations.test.ts +122 -0
- package/src/utils/serialize-mutations.ts +68 -3
- package/src/wearables/memory-gen.test.ts +31 -9
- package/src/wearables/memory-gen.ts +95 -55
- package/src/wearables/pipeline.test.ts +10 -7
- package/src/wearables/service.test.ts +6 -8
- package/src/wearables/service.ts +2 -2
- package/src/write-envelope.extension.test.ts +111 -0
- package/src/write-envelope.test.ts +683 -0
- package/src/write-envelope.ts +902 -0
- package/src/write-quarantine.test.ts +193 -0
- package/src/write-quarantine.ts +241 -0
- package/src/write-rate-limiter.test.ts +105 -0
- package/src/write-rate-limiter.ts +135 -0
- package/src/write-sealed-parity.test.ts +204 -0
- package/dist/chunk-2VN4JAX7.js.map +0 -1
- package/dist/chunk-37CTGERM.js.map +0 -1
- package/dist/chunk-7ICYQUOL.js.map +0 -1
- package/dist/chunk-AD6AMF2N.js.map +0 -1
- package/dist/chunk-AHLPZ2SF.js.map +0 -1
- package/dist/chunk-ASKEM4AR.js.map +0 -1
- package/dist/chunk-B3F4CWQR.js.map +0 -1
- package/dist/chunk-BCDKBDSY.js.map +0 -1
- package/dist/chunk-BFPETA3S.js.map +0 -1
- package/dist/chunk-BFVEEB7W.js.map +0 -1
- package/dist/chunk-E5BK6CGV.js +0 -335
- package/dist/chunk-E5BK6CGV.js.map +0 -1
- package/dist/chunk-EEARRVZ2.js.map +0 -1
- package/dist/chunk-F7AU34FC.js.map +0 -1
- package/dist/chunk-FBNWOMCE.js.map +0 -1
- package/dist/chunk-FTYDWKO6.js.map +0 -1
- package/dist/chunk-GMSDQUCR.js.map +0 -1
- package/dist/chunk-GWTFLF2P.js.map +0 -1
- package/dist/chunk-IFJ23BHU.js.map +0 -1
- package/dist/chunk-IKQTFQMI.js.map +0 -1
- package/dist/chunk-J2HSAU72.js.map +0 -1
- package/dist/chunk-JMBVCAR4.js.map +0 -1
- package/dist/chunk-KQDNAXOM.js.map +0 -1
- package/dist/chunk-KSBEEMQF.js.map +0 -1
- package/dist/chunk-KSNVDPDF.js.map +0 -1
- package/dist/chunk-LC7OODWZ.js.map +0 -1
- package/dist/chunk-LTJAMRGI.js.map +0 -1
- package/dist/chunk-ND5M64JJ.js.map +0 -1
- package/dist/chunk-NUWYOKS6.js.map +0 -1
- package/dist/chunk-NWTGD4AN.js.map +0 -1
- package/dist/chunk-OBMR4VIX.js.map +0 -1
- package/dist/chunk-ODPLEWB6.js.map +0 -1
- package/dist/chunk-PHK3HARR.js +0 -32
- package/dist/chunk-PHK3HARR.js.map +0 -1
- package/dist/chunk-RANHFI3P.js +0 -8
- package/dist/chunk-RANHFI3P.js.map +0 -1
- package/dist/chunk-RBQLJSJ7.js.map +0 -1
- package/dist/chunk-RULE4VG5.js.map +0 -1
- package/dist/chunk-SVOZFLIQ.js +0 -16
- package/dist/chunk-SVOZFLIQ.js.map +0 -1
- package/dist/chunk-TXLGHDHS.js.map +0 -1
- package/dist/chunk-UN3CH3CO.js +0 -118
- package/dist/chunk-UN3CH3CO.js.map +0 -1
- package/dist/chunk-VSMRDBFT.js +0 -17
- package/dist/chunk-VSMRDBFT.js.map +0 -1
- package/dist/chunk-WU46YPY6.js.map +0 -1
- package/dist/chunk-X47LWMKA.js.map +0 -1
- package/dist/chunk-X64YLC24.js.map +0 -1
- package/dist/chunk-XVLEGMJI.js.map +0 -1
- package/dist/chunk-YF6FMLBT.js.map +0 -1
- package/dist/resolution-VH4NGENZ.js +0 -12
- /package/dist/{capsule-crypto-CZJSLEFG.js.map → access-citation.js.map} +0 -0
- /package/dist/{contradiction-scan-J57T5QV7.js.map → access-memory-search-fanout.js.map} +0 -0
- /package/dist/{dreams-ledger-6UODQOX6.js.map → access-recall-concurrency.js.map} +0 -0
- /package/dist/{graph-edge-decay-FO7AM4UR.js.map → access-recall-response.js.map} +0 -0
- /package/dist/{resolution-VH4NGENZ.js.map → bounded-jsonl-state.js.map} +0 -0
- /package/dist/{capsule-merge-Z2HUO6IK.js.map → capsule-merge-5KKJQBWQ.js.map} +0 -0
- /package/dist/{chunk-A3GOMRJG.js.map → chunk-23L3IXFD.js.map} +0 -0
- /package/dist/{chunk-MRHFJV44.js.map → chunk-2DQ2XREU.js.map} +0 -0
- /package/dist/{chunk-L2B3EE7B.js.map → chunk-2QMKMVHH.js.map} +0 -0
- /package/dist/{chunk-6CALL5VN.js.map → chunk-2UFO7X4Q.js.map} +0 -0
- /package/dist/{chunk-2MR3MFQB.js.map → chunk-2VEOKUPP.js.map} +0 -0
- /package/dist/{chunk-RHOZ5LLO.js.map → chunk-347WD2LE.js.map} +0 -0
- /package/dist/{chunk-5S7Z5SHA.js.map → chunk-34RC5RT7.js.map} +0 -0
- /package/dist/{chunk-KGWXHWAH.js.map → chunk-3QAH2S33.js.map} +0 -0
- /package/dist/{chunk-ZIDSD6VC.js.map → chunk-3Y224NYC.js.map} +0 -0
- /package/dist/{chunk-VFSP73LP.js.map → chunk-45GF7Y3V.js.map} +0 -0
- /package/dist/{chunk-OEHCMALU.js.map → chunk-5I4M26Q7.js.map} +0 -0
- /package/dist/{chunk-2E6G7FCE.js.map → chunk-5Q7EVV4X.js.map} +0 -0
- /package/dist/{chunk-VZ5OJE4X.js.map → chunk-5VQJBH2G.js.map} +0 -0
- /package/dist/{chunk-PUBTHW5O.js.map → chunk-6DRPPQEJ.js.map} +0 -0
- /package/dist/{chunk-4LEF6XWJ.js.map → chunk-6O22TZSB.js.map} +0 -0
- /package/dist/{chunk-ZQ7UBUZ6.js.map → chunk-6QYST5XN.js.map} +0 -0
- /package/dist/{chunk-W4PGTAS2.js.map → chunk-6WAFYNVT.js.map} +0 -0
- /package/dist/{chunk-R5VAVVHP.js.map → chunk-72A4L5JJ.js.map} +0 -0
- /package/dist/{chunk-3FAMU5TX.js.map → chunk-A6USBZTO.js.map} +0 -0
- /package/dist/{chunk-TXVD7PLT.js.map → chunk-A72SWTWW.js.map} +0 -0
- /package/dist/{chunk-FC77VUX5.js.map → chunk-A7Q43EUZ.js.map} +0 -0
- /package/dist/{chunk-UJBESW6X.js.map → chunk-AE7WMV4V.js.map} +0 -0
- /package/dist/{chunk-OKUEZOGW.js.map → chunk-AITCS2RC.js.map} +0 -0
- /package/dist/{chunk-OC35KQIN.js.map → chunk-AJ7QCSIS.js.map} +0 -0
- /package/dist/{chunk-FNMFJWBY.js.map → chunk-ANEUPF6O.js.map} +0 -0
- /package/dist/{chunk-2A3OXAP2.js.map → chunk-B7RWBZXW.js.map} +0 -0
- /package/dist/{chunk-N3JDIRBW.js.map → chunk-BLAKS3CP.js.map} +0 -0
- /package/dist/{chunk-M7VGG3ID.js.map → chunk-BV5WMSIJ.js.map} +0 -0
- /package/dist/{chunk-2BFLDH5F.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-UXKMMNJD.js.map → chunk-C23BYTJV.js.map} +0 -0
- /package/dist/{chunk-JZHHREBL.js.map → chunk-C3AKM55W.js.map} +0 -0
- /package/dist/{chunk-RP7YXA67.js.map → chunk-C5JF6EZ7.js.map} +0 -0
- /package/dist/{chunk-DDGV7NAX.js.map → chunk-CQMEM5CC.js.map} +0 -0
- /package/dist/{chunk-A7B4RMQG.js.map → chunk-CXZQOVIE.js.map} +0 -0
- /package/dist/{chunk-7N2RUBAP.js.map → chunk-DDA47TES.js.map} +0 -0
- /package/dist/{chunk-64SE4X5G.js.map → chunk-DEBHXHJR.js.map} +0 -0
- /package/dist/{chunk-EHK6KZHK.js.map → chunk-DNHVPZOD.js.map} +0 -0
- /package/dist/{chunk-437S3G37.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-LZZNTPLR.js.map → chunk-DX3XRGLH.js.map} +0 -0
- /package/dist/{chunk-7MW3CVLD.js.map → chunk-ES36HTSC.js.map} +0 -0
- /package/dist/{chunk-TN7THW5U.js.map → chunk-ET356KSB.js.map} +0 -0
- /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
- /package/dist/{chunk-7LFXDGLH.js.map → chunk-F7GAIWFA.js.map} +0 -0
- /package/dist/{chunk-IKSELOIV.js.map → chunk-FFPJINJE.js.map} +0 -0
- /package/dist/{chunk-V53GJUSL.js.map → chunk-FUTF72MJ.js.map} +0 -0
- /package/dist/{chunk-5UNWK7KU.js.map → chunk-GFPZS3F5.js.map} +0 -0
- /package/dist/{chunk-G6NKALRN.js.map → chunk-H4WG3UQZ.js.map} +0 -0
- /package/dist/{chunk-HLTAPHZZ.js.map → chunk-HNZKVLAN.js.map} +0 -0
- /package/dist/{chunk-5EZXHU36.js.map → chunk-HYQJQGD3.js.map} +0 -0
- /package/dist/{chunk-TRWPCR6P.js.map → chunk-JECBQBEX.js.map} +0 -0
- /package/dist/{chunk-HG32URJJ.js.map → chunk-JYIFGGEM.js.map} +0 -0
- /package/dist/{chunk-VA4WSW54.js.map → chunk-JYIJNNN3.js.map} +0 -0
- /package/dist/{chunk-L5HJQC36.js.map → chunk-K2TDK7GG.js.map} +0 -0
- /package/dist/{chunk-MKDRQAA3.js.map → chunk-KAVBJSBQ.js.map} +0 -0
- /package/dist/{chunk-4OKLXWDZ.js.map → chunk-KNB7IBBU.js.map} +0 -0
- /package/dist/{chunk-QLULYKWZ.js.map → chunk-KSXJOC4F.js.map} +0 -0
- /package/dist/{chunk-JI5AVXYO.js.map → chunk-LEPOP46W.js.map} +0 -0
- /package/dist/{chunk-O7BBFJLP.js.map → chunk-LTAVSOZW.js.map} +0 -0
- /package/dist/{chunk-2IZAGAJR.js.map → chunk-LULR4IUW.js.map} +0 -0
- /package/dist/{chunk-WMWVO45V.js.map → chunk-MC6XO7T4.js.map} +0 -0
- /package/dist/{chunk-D6RIFG4O.js.map → chunk-MNB5RMAY.js.map} +0 -0
- /package/dist/{chunk-67ZCJLJY.js.map → chunk-MYFQ3ED4.js.map} +0 -0
- /package/dist/{chunk-V3UE5I5F.js.map → chunk-MYVPLJOO.js.map} +0 -0
- /package/dist/{chunk-MTWKDOVO.js.map → chunk-NLE6TSLG.js.map} +0 -0
- /package/dist/{chunk-DBRYEIGY.js.map → chunk-OJP3N7UK.js.map} +0 -0
- /package/dist/{chunk-SMX5267P.js.map → chunk-OZKOPQCM.js.map} +0 -0
- /package/dist/{chunk-JCK7V6SN.js.map → chunk-P65YJEEL.js.map} +0 -0
- /package/dist/{chunk-MTR7BZQN.js.map → chunk-PBGWYM3H.js.map} +0 -0
- /package/dist/{chunk-AXTXN4T6.js.map → chunk-PWFCHOB3.js.map} +0 -0
- /package/dist/{chunk-FDPZVY6D.js.map → chunk-QFN4U7AG.js.map} +0 -0
- /package/dist/{chunk-K2ZLHESQ.js.map → chunk-QIEUU4UK.js.map} +0 -0
- /package/dist/{chunk-3D6AFGQR.js.map → chunk-QVT3E4CE.js.map} +0 -0
- /package/dist/{chunk-SFQ6QNL7.js.map → chunk-R6YJI3HE.js.map} +0 -0
- /package/dist/{chunk-5CJVLG3H.js.map → chunk-RFDD3B7W.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-UTRJFDP2.js.map → chunk-S2BBISHU.js.map} +0 -0
- /package/dist/{chunk-IALLX7EE.js.map → chunk-S2FSBU4H.js.map} +0 -0
- /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-PK5XBDA6.js.map → chunk-U3ZAVRP3.js.map} +0 -0
- /package/dist/{chunk-4KJLYTLS.js.map → chunk-V57NLO5P.js.map} +0 -0
- /package/dist/{chunk-FLVL4L3L.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-7XGSIUP5.js.map → chunk-W4FBGYGK.js.map} +0 -0
- /package/dist/{chunk-6SXVCD7W.js.map → chunk-W7IGLX4G.js.map} +0 -0
- /package/dist/{chunk-KAWTOYAW.js.map → chunk-WLZYGLJ4.js.map} +0 -0
- /package/dist/{chunk-W5NKDU24.js.map → chunk-WON4APQY.js.map} +0 -0
- /package/dist/{chunk-NKCPUHCI.js.map → chunk-WZFAPHIK.js.map} +0 -0
- /package/dist/{chunk-KQPJLK3X.js.map → chunk-XL24QQ63.js.map} +0 -0
- /package/dist/{chunk-4B4MUS5D.js.map → chunk-YROFNEG5.js.map} +0 -0
- /package/dist/{chunk-VRAD2FGO.js.map → chunk-Z54EM5YZ.js.map} +0 -0
- /package/dist/{first-start-migration-TI67YMLG.js.map → first-start-migration-CSRHCJIQ.js.map} +0 -0
- /package/dist/{forget-CQCLB5LB.js.map → forget-HRPLVB3W.js.map} +0 -0
- /package/dist/{purge-NDWV6WYD.js.map → purge-IRF47ZTX.js.map} +0 -0
- /package/dist/{tier-stats-KV7IWCJR.js.map → tier-stats-QEJSPFV2.js.map} +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
import { probeEncryptedRegularFileHeader, SECURE_STORE_ENVELOPE_OVERHEAD_BYTES } from "../secure-store/secure-fs.js";
|
|
4
|
+
import { STATE_FILE_MAX_DECRYPT_BYTES } from "../storage/secure-line-reader.js";
|
|
5
|
+
import type { StorageManager } from "../index.js";
|
|
6
|
+
import {
|
|
7
|
+
rebuildMemoryLifecycleLedger,
|
|
8
|
+
type RebuildMemoryLifecycleLedgerResult,
|
|
9
|
+
} from "./rebuild-memory-lifecycle-ledger.js";
|
|
10
|
+
|
|
11
|
+
export interface RebuildMemoryLifecycleLedgerCliCommandOptions {
|
|
12
|
+
memoryDir: string;
|
|
13
|
+
write?: boolean;
|
|
14
|
+
now?: Date;
|
|
15
|
+
/**
|
|
16
|
+
* Live storage for secure-store deployments (#2033). When the store is
|
|
17
|
+
* encrypted at rest, the rebuild must read encrypted memories and re-encrypt
|
|
18
|
+
* the rewritten ledger through this unlocked StorageManager; a keyless manager
|
|
19
|
+
* would read with no key and rewrite the ledger as plaintext. The command
|
|
20
|
+
* refuses when the on-disk ledger is encrypted and no unlocked key is present.
|
|
21
|
+
*/
|
|
22
|
+
storage?: StorageManager;
|
|
23
|
+
/**
|
|
24
|
+
* Read/decrypt cap the rewritten ledger must land strictly below. Defaults to
|
|
25
|
+
* {@link STATE_FILE_MAX_DECRYPT_BYTES} (the reader's whole-file refusal cap).
|
|
26
|
+
* Exposed as an override so recovery tooling and tests can bound the rewrite
|
|
27
|
+
* deterministically, mirroring the scheduler's `lifecycleLedgerMaxBytes` seam.
|
|
28
|
+
*/
|
|
29
|
+
maxLedgerBytesCap?: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function runRebuildMemoryLifecycleLedgerCliCommand(
|
|
33
|
+
options: RebuildMemoryLifecycleLedgerCliCommandOptions,
|
|
34
|
+
): Promise<RebuildMemoryLifecycleLedgerResult> {
|
|
35
|
+
const storage = options.storage;
|
|
36
|
+
const ledgerPath = path.join(options.memoryDir, "state", "memory-lifecycle-ledger.jsonl");
|
|
37
|
+
const encrypted = await probeEncryptedRegularFileHeader(ledgerPath);
|
|
38
|
+
// Refuse a keyless plaintext rewrite of an encrypted-at-rest ledger (#2033):
|
|
39
|
+
// without an unlocked secure StorageManager the rebuild would read encrypted
|
|
40
|
+
// memories with no key and rewrite the ledger as plaintext, defeating
|
|
41
|
+
// encryption-at-rest. Fail safely and point the operator at the unlock step.
|
|
42
|
+
if (encrypted && !(storage?.isSecureStoreUnlocked() ?? false)) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
"rebuild-memory-lifecycle-ledger: secure store is locked; refusing to rebuild the "
|
|
45
|
+
+ "lifecycle ledger, which would read encrypted memories with no key and rewrite the "
|
|
46
|
+
+ "ledger as plaintext. Run `remnic secure-store unlock` first, then re-run with --write.",
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
// This command is the advertised recovery for an over-cap ledger, so it must
|
|
50
|
+
// give the SAME guarantees as background compaction (#2033): (1) preserve
|
|
51
|
+
// append-only history frontmatter cannot reconstruct (explicit_capture_accepted,
|
|
52
|
+
// imported, promoted) instead of silently dropping it, and (2) bound the
|
|
53
|
+
// rewritten ledger under the read/decrypt cap so the repaired ledger is
|
|
54
|
+
// readable. Bound the PLAINTEXT payload, reserving the secure-store envelope
|
|
55
|
+
// (+1 byte) whenever the REPLACEMENT will be encrypted — NOT only when the
|
|
56
|
+
// current header is encrypted. A plaintext ledger rewritten through an unlocked
|
|
57
|
+
// encrypt-on-write store becomes encrypted, so it needs the reserve even though
|
|
58
|
+
// its current header is plaintext; base the decision on
|
|
59
|
+
// `willEncryptStateWrites()` exactly as auto-compaction does (#2033 write-mode
|
|
60
|
+
// finding), so the on-disk file lands STRICTLY under the cap.
|
|
61
|
+
const cap = options.maxLedgerBytesCap ?? STATE_FILE_MAX_DECRYPT_BYTES;
|
|
62
|
+
const replacementEncrypted = encrypted || (storage?.willEncryptStateWrites() ?? false);
|
|
63
|
+
const maxLedgerBytes = replacementEncrypted
|
|
64
|
+
? cap - SECURE_STORE_ENVELOPE_OVERHEAD_BYTES - 1
|
|
65
|
+
: cap - 1;
|
|
66
|
+
return rebuildMemoryLifecycleLedger({
|
|
67
|
+
memoryDir: options.memoryDir,
|
|
68
|
+
dryRun: options.write !== true,
|
|
69
|
+
now: options.now,
|
|
70
|
+
// Carry the live (unlocked) secure StorageManager so encrypted memories
|
|
71
|
+
// decrypt on read and the rewritten ledger stays encrypted at rest; a
|
|
72
|
+
// plaintext store passes a plaintext manager here, which is correct.
|
|
73
|
+
storage,
|
|
74
|
+
preserveExistingEvents: true,
|
|
75
|
+
maxLedgerBytes,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
@@ -2,18 +2,80 @@ import path from "node:path";
|
|
|
2
2
|
import { stat } from "node:fs/promises";
|
|
3
3
|
import { StorageManager } from "../storage.js";
|
|
4
4
|
import { log } from "../logger.js";
|
|
5
|
+
import { displayErrorDetail } from "../runtime/better-sqlite.js";
|
|
5
6
|
import type { MemoryLifecycleEvent } from "../types.js";
|
|
6
7
|
import { toBackupStamp } from "./backup-stamp.js";
|
|
7
|
-
import { writeFileAtomically } from "./atomic-file.js";
|
|
8
|
+
import { copyExistingFileToBackup, writeFileAtomically } from "./atomic-file.js";
|
|
8
9
|
import {
|
|
9
10
|
buildLifecycleEventsForMemory,
|
|
11
|
+
compareMemoryLifecycleEvents,
|
|
10
12
|
sortMemoryLifecycleEvents,
|
|
13
|
+
memoryLifecycleLedgerLockPath,
|
|
14
|
+
MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS,
|
|
11
15
|
} from "../memory-lifecycle-ledger-utils.js";
|
|
16
|
+
import { withHeldFileLock, type HeldFileLockOptions, type HeldFileLockController } from "../utils/serialize-mutations.js";
|
|
17
|
+
import { probeEncryptedRegularFileHeader } from "../secure-store/secure-fs.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Event types `buildLifecycleEventsForMemory` reconstructs from frontmatter.
|
|
21
|
+
* Everything else in the ledger is append-only history with no frontmatter
|
|
22
|
+
* equivalent and must be carried over by a preserving rebuild (issue #1910).
|
|
23
|
+
*/
|
|
24
|
+
const FRONTMATTER_DERIVED_EVENT_TYPES: Record<string, true> = {
|
|
25
|
+
created: true,
|
|
26
|
+
updated: true,
|
|
27
|
+
superseded: true,
|
|
28
|
+
archived: true,
|
|
29
|
+
};
|
|
12
30
|
|
|
13
31
|
export interface RebuildMemoryLifecycleLedgerOptions {
|
|
14
32
|
memoryDir: string;
|
|
15
33
|
dryRun?: boolean;
|
|
16
34
|
now?: Date;
|
|
35
|
+
/**
|
|
36
|
+
* Active storage context (issue #1910). When provided, memories are read
|
|
37
|
+
* through it (so encrypted-at-rest memories in a secure-store deployment are
|
|
38
|
+
* decrypted with the live key) and the rebuilt ledger is rewritten through
|
|
39
|
+
* its secure writer (so it stays encrypted at rest). Its `dir` MUST equal
|
|
40
|
+
* `memoryDir`. When omitted, a fresh plaintext `StorageManager` is used and
|
|
41
|
+
* the ledger is written as plaintext — the CLI default.
|
|
42
|
+
*/
|
|
43
|
+
storage?: StorageManager;
|
|
44
|
+
/**
|
|
45
|
+
* Preserve append-only lifecycle events that have no frontmatter equivalent
|
|
46
|
+
* (issue #1910). `buildLifecycleEventsForMemory` only reconstructs
|
|
47
|
+
* `created`/`updated`/`superseded`/`archived` from frontmatter, so a bare
|
|
48
|
+
* rebuild silently drops history like `explicit_capture_accepted`,
|
|
49
|
+
* `explicit_capture_queued`, `imported`, `promoted`, `merged`, `restored`,
|
|
50
|
+
* and `rejected`. When true, the existing ledger's non-reconstructable rows
|
|
51
|
+
* are read (via the same secure/permissive `readAllMemoryLifecycleEvents`
|
|
52
|
+
* path), merged with the rebuilt rows, deduplicated by `eventId`, and sorted
|
|
53
|
+
* canonically. Background auto-compaction sets this so it never loses events;
|
|
54
|
+
* the manual/CLI repair rebuild leaves it off (reconstruct purely from
|
|
55
|
+
* frontmatter).
|
|
56
|
+
*/
|
|
57
|
+
preserveExistingEvents?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Override the ledger-lock acquisition timing (issue #2033). Only
|
|
60
|
+
* `maxWaitMs`/`pollMs` are honored; `staleMs` stays fixed at
|
|
61
|
+
* `MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS`. Used by tests to force the
|
|
62
|
+
* lock-acquisition-failure branch (`acquired=false`) deterministically
|
|
63
|
+
* without a multi-second wait.
|
|
64
|
+
*/
|
|
65
|
+
lockOptions?: Pick<HeldFileLockOptions, "maxWaitMs" | "pollMs">;
|
|
66
|
+
/**
|
|
67
|
+
* Upper bound (bytes) on the rewritten ledger when preserving events (issue
|
|
68
|
+
* #2033). A preserving compaction carries over ALL append-only history, which
|
|
69
|
+
* — if the history alone is large — could leave the rewritten ledger over the
|
|
70
|
+
* whole-file read/decrypt cap (STATE_FILE_MAX_DECRYPT_BYTES), the exact
|
|
71
|
+
* unreadable-ledger failure compaction exists to prevent. When set and the
|
|
72
|
+
* preserved payload would exceed it, the OLDEST rows are dropped from the
|
|
73
|
+
* active ledger until it fits; because the full pre-compaction ledger is
|
|
74
|
+
* copied verbatim to the timestamped backup first, those rows are archived,
|
|
75
|
+
* not lost. Ignored when `preserveExistingEvents` is off (a frontmatter-only
|
|
76
|
+
* rebuild is already bounded by the corpus). `0`/undefined disables bounding.
|
|
77
|
+
*/
|
|
78
|
+
maxLedgerBytes?: number;
|
|
17
79
|
}
|
|
18
80
|
|
|
19
81
|
export interface SkippedLifecycleBlankIdMemory {
|
|
@@ -34,12 +96,84 @@ export interface RebuildMemoryLifecycleLedgerResult {
|
|
|
34
96
|
backupPath?: string;
|
|
35
97
|
skippedBlankIdMemories: SkippedLifecycleBlankIdMemory[];
|
|
36
98
|
skippedDuplicateEvents: SkippedDuplicateLifecycleEvent[];
|
|
99
|
+
/**
|
|
100
|
+
* Count of existing-ledger rows carried over beyond the frontmatter
|
|
101
|
+
* reconstruction (only set when `preserveExistingEvents` is on; issue #1910):
|
|
102
|
+
* append-only history with no frontmatter equivalent, plus any
|
|
103
|
+
* frontmatter-derived row that raced in after the corpus scan and so was not
|
|
104
|
+
* reproduced by the reconstruction (#2033).
|
|
105
|
+
*/
|
|
106
|
+
preservedAppendOnlyRows?: number;
|
|
107
|
+
/**
|
|
108
|
+
* Count of oldest rows dropped from the ACTIVE ledger to keep it under
|
|
109
|
+
* `maxLedgerBytes` (issue #2033). They remain in the verbatim timestamped
|
|
110
|
+
* backup, so this is a bound-and-archive, not a loss. Set only when bounding
|
|
111
|
+
* actually trimmed rows.
|
|
112
|
+
*/
|
|
113
|
+
archivedOverflowRows?: number;
|
|
114
|
+
/**
|
|
115
|
+
* Whether the active ledger was actually backed up and rewritten (issue #2033
|
|
116
|
+
* thread PRRT_kwDORJXyws6SExst). A preserving write-mode rebuild that would
|
|
117
|
+
* reproduce the current ledger byte-for-byte (same decrypted content AND same
|
|
118
|
+
* at-rest format) skips the backup+rewrite, so callers can distinguish a real
|
|
119
|
+
* compaction from a no-op and avoid re-archiving an unchanged ledger every
|
|
120
|
+
* interval. `true` for every dry run's non-write preview is never set — only
|
|
121
|
+
* write-mode results carry it; defaults to `false` when no rewrite happened.
|
|
122
|
+
*/
|
|
123
|
+
rewritten?: boolean;
|
|
37
124
|
}
|
|
38
125
|
|
|
39
126
|
function isNodeError(err: unknown): err is NodeJS.ErrnoException {
|
|
40
127
|
return typeof err === "object" && err !== null && "code" in err;
|
|
41
128
|
}
|
|
42
129
|
|
|
130
|
+
/** Serialized on-disk size (bytes, incl. trailing newline) of one ledger row. */
|
|
131
|
+
function lifecycleRowBytes(event: MemoryLifecycleEvent): number {
|
|
132
|
+
return Buffer.byteLength(`${JSON.stringify(event)}\n`, "utf8");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Keep the NEWEST canonically-ordered events whose serialized payload fits
|
|
137
|
+
* strictly under `cap` bytes (issue #2033). Recency is by `timestamp` (newest
|
|
138
|
+
* first), tie-broken by the canonical comparator, so a large append-only
|
|
139
|
+
* history is trimmed to its most recent rows rather than to a single memoryId
|
|
140
|
+
* group (the ledger's on-disk order is by memoryId then time).
|
|
141
|
+
*
|
|
142
|
+
* A row too large to fit the remaining budget is SKIPPED, and scanning
|
|
143
|
+
* continues to older rows that still fit — one oversized (or future-dated,
|
|
144
|
+
* hence recency-first) row cannot truncate the entire older history. The kept
|
|
145
|
+
* subset is returned in the input's canonical order; the caller relies on the
|
|
146
|
+
* verbatim backup to retain the dropped rows.
|
|
147
|
+
*/
|
|
148
|
+
export function boundLifecycleEventsToByteCap(
|
|
149
|
+
events: MemoryLifecycleEvent[],
|
|
150
|
+
cap: number,
|
|
151
|
+
): { kept: MemoryLifecycleEvent[]; dropped: number } {
|
|
152
|
+
if (!(cap > 0)) return { kept: events, dropped: 0 };
|
|
153
|
+
const sizes = new Map<MemoryLifecycleEvent, number>();
|
|
154
|
+
let total = 0;
|
|
155
|
+
for (const event of events) {
|
|
156
|
+
const bytes = lifecycleRowBytes(event);
|
|
157
|
+
sizes.set(event, bytes);
|
|
158
|
+
total += bytes;
|
|
159
|
+
}
|
|
160
|
+
if (total <= cap) return { kept: events, dropped: 0 };
|
|
161
|
+
const byRecency = [...events].sort((a, b) => {
|
|
162
|
+
if (a.timestamp !== b.timestamp) return b.timestamp.localeCompare(a.timestamp);
|
|
163
|
+
return -compareMemoryLifecycleEvents(a, b);
|
|
164
|
+
});
|
|
165
|
+
const keep = new Set<MemoryLifecycleEvent>();
|
|
166
|
+
let running = 0;
|
|
167
|
+
for (const event of byRecency) {
|
|
168
|
+
const bytes = sizes.get(event)!;
|
|
169
|
+
if (running + bytes > cap) continue; // skip this row, keep scanning older rows that still fit
|
|
170
|
+
running += bytes;
|
|
171
|
+
keep.add(event);
|
|
172
|
+
}
|
|
173
|
+
const kept = events.filter((event) => keep.has(event));
|
|
174
|
+
return { kept, dropped: events.length - kept.length };
|
|
175
|
+
}
|
|
176
|
+
|
|
43
177
|
export async function backupExistingLedger(
|
|
44
178
|
memoryDir: string,
|
|
45
179
|
outputPath: string,
|
|
@@ -71,7 +205,14 @@ export async function rebuildMemoryLifecycleLedger(
|
|
|
71
205
|
const dryRun = options.dryRun !== false;
|
|
72
206
|
const now = options.now ?? new Date();
|
|
73
207
|
const outputPath = path.join(options.memoryDir, "state", "memory-lifecycle-ledger.jsonl");
|
|
74
|
-
const storage = new StorageManager(options.memoryDir);
|
|
208
|
+
const storage = options.storage ?? new StorageManager(options.memoryDir);
|
|
209
|
+
if (options.storage && path.resolve(storage.dir) !== path.resolve(options.memoryDir)) {
|
|
210
|
+
throw new Error(
|
|
211
|
+
`rebuildMemoryLifecycleLedger: storage.dir (${storage.dir}) must match `
|
|
212
|
+
+ `memoryDir (${options.memoryDir})`,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
const secureRewrite = options.storage !== undefined;
|
|
75
216
|
const tiers = [
|
|
76
217
|
await storage.readAllMemories(),
|
|
77
218
|
await storage.readAllColdMemories(),
|
|
@@ -119,24 +260,247 @@ export async function rebuildMemoryLifecycleLedger(
|
|
|
119
260
|
events.push(event);
|
|
120
261
|
}
|
|
121
262
|
|
|
263
|
+
let finalEvents = events;
|
|
264
|
+
let preservedAppendOnlyRows: number | undefined;
|
|
265
|
+
let archivedOverflowRows: number | undefined;
|
|
122
266
|
let backupPath: string | undefined;
|
|
267
|
+
let rewritten = false;
|
|
268
|
+
// The preserve-read + whole-file rewrite are serialized against concurrent
|
|
269
|
+
// lifecycle appends ONLY in write mode (issue #1910, codex):
|
|
270
|
+
// appendMemoryLifecycleEvents holds this same cross-process lock, so an event
|
|
271
|
+
// appended after the preserve-read but before the atomic rename waits and
|
|
272
|
+
// lands on the compacted ledger instead of being clobbered by the rename. A
|
|
273
|
+
// DRY RUN takes no lock — it reads the ledger read-only to compute the
|
|
274
|
+
// preserve/merge/byte-cap PREVIEW and never rewrites, so it must not block
|
|
275
|
+
// appends (#2033 Cursor). The corpus scan above stays outside the lock in
|
|
276
|
+
// both modes — frontmatter-derived rows come from the memory files.
|
|
277
|
+
const runLedgerCriticalSection = async (
|
|
278
|
+
acquired: boolean,
|
|
279
|
+
lock: HeldFileLockController | null,
|
|
280
|
+
): Promise<void> => {
|
|
281
|
+
// A WRITE that read or rewrote the ledger without the lock could race a
|
|
282
|
+
// concurrent append/rewrite and lose data, so REFUSE the unlocked fallback
|
|
283
|
+
// withHeldFileLock takes on acquisition timeout (issue #2033 CodeRabbit
|
|
284
|
+
// Critical / codex). A dry run passes lock=null and acquired=true: it never
|
|
285
|
+
// reaches the rewrite, so the unlocked preview read is safe.
|
|
286
|
+
if (!dryRun && !acquired) {
|
|
287
|
+
throw new Error(
|
|
288
|
+
"lifecycle ledger rebuild aborted: could not acquire the ledger lock within the "
|
|
289
|
+
+ "acquisition budget; refusing to read or rewrite unlocked so a concurrent append "
|
|
290
|
+
+ "or compaction cannot be clobbered (issue #1910).",
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
if (options.preserveExistingEvents) {
|
|
294
|
+
// Merge the frontmatter reconstruction (`events`) with the CURRENT ledger
|
|
295
|
+
// so compaction never deletes a lifecycle row that raced the scan (issue
|
|
296
|
+
// #1910, #2033). Read the existing ledger through the uncapped BUFFER
|
|
297
|
+
// path — it decrypts with the live key when `storage` carries the secure
|
|
298
|
+
// context and bypasses the whole-file string decrypt cap, so an oversize
|
|
299
|
+
// encrypted ledger (the exact file compaction must shrink) is still
|
|
300
|
+
// readable here rather than aborting (#2033 Cursor High).
|
|
301
|
+
// preserveExistingEvents means "never lose history": if the current
|
|
302
|
+
// ledger genuinely cannot be read (corruption, or a locked required
|
|
303
|
+
// store), ABORT rather than rewrite from frontmatter only and silently
|
|
304
|
+
// drop that history. An absent ledger reads as [] (ENOENT swallowed
|
|
305
|
+
// downstream), so a throw here is always a real read failure.
|
|
306
|
+
let existing: MemoryLifecycleEvent[];
|
|
307
|
+
try {
|
|
308
|
+
existing = await storage.readAllMemoryLifecycleEventsForCompaction();
|
|
309
|
+
} catch (err) {
|
|
310
|
+
throw new Error(
|
|
311
|
+
`lifecycle ledger rebuild aborted: cannot read existing events to preserve `
|
|
312
|
+
+ `(${displayErrorDetail(err) || "unknown error"})`,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
// The corpus scan (`events`) runs OUTSIDE the lock and is therefore a
|
|
316
|
+
// stale snapshot; `existing` is read here under the lock and is
|
|
317
|
+
// authoritative for what the ledger holds at rewrite time. A
|
|
318
|
+
// frontmatter-derived row (created/updated/superseded/archived) is safe to
|
|
319
|
+
// collapse into the reconstruction ONLY when the scan actually reproduced
|
|
320
|
+
// the same logical event — same (memoryId, eventType, timestamp), which is
|
|
321
|
+
// exactly what the live append stamps (fm.created/updated/...) and what
|
|
322
|
+
// makeRebuiltMemoryLifecycleEvent emits. A frontmatter-derived row whose
|
|
323
|
+
// content key the reconstruction did NOT produce raced in after the scan
|
|
324
|
+
// (a memory created/updated between the scan and this locked read); the
|
|
325
|
+
// reconstruction has no equivalent, so dropping it by eventType alone
|
|
326
|
+
// would delete it. Preserve it instead, deduped by content key so a
|
|
327
|
+
// retried append of the same logical event still collapses to one. Rows
|
|
328
|
+
// that are not frontmatter-derived are append-only history with no
|
|
329
|
+
// reconstruction — always carried over, deduped by eventId in the merge.
|
|
330
|
+
const contentKey = (event: MemoryLifecycleEvent): string =>
|
|
331
|
+
`${event.memoryId}\u0000${event.eventType}\u0000${event.timestamp}`;
|
|
332
|
+
const reconstructedKeys = new Set(events.map(contentKey));
|
|
333
|
+
const racedFrontmatterByKey = new Map<string, MemoryLifecycleEvent>();
|
|
334
|
+
const appendOnly: MemoryLifecycleEvent[] = [];
|
|
335
|
+
for (const event of existing) {
|
|
336
|
+
if (!FRONTMATTER_DERIVED_EVENT_TYPES[event.eventType]) {
|
|
337
|
+
appendOnly.push(event);
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
const key = contentKey(event);
|
|
341
|
+
if (reconstructedKeys.has(key)) continue; // collapsed into reconstruction
|
|
342
|
+
if (!racedFrontmatterByKey.has(key)) racedFrontmatterByKey.set(key, event);
|
|
343
|
+
}
|
|
344
|
+
const mergedById = new Map<string, MemoryLifecycleEvent>();
|
|
345
|
+
for (const event of sortMemoryLifecycleEvents([
|
|
346
|
+
...events,
|
|
347
|
+
...racedFrontmatterByKey.values(),
|
|
348
|
+
...appendOnly,
|
|
349
|
+
])) {
|
|
350
|
+
if (!mergedById.has(event.eventId)) mergedById.set(event.eventId, event);
|
|
351
|
+
}
|
|
352
|
+
finalEvents = [...mergedById.values()];
|
|
353
|
+
preservedAppendOnlyRows = finalEvents.length - events.length;
|
|
354
|
+
// Bound the rewritten ledger so a preserving compaction can never leave it
|
|
355
|
+
// over the whole-file read/decrypt cap (#2033). This must run whenever a
|
|
356
|
+
// cap is set — NOT only when `existing.length > 0`: an oversized on-disk
|
|
357
|
+
// ledger whose every row fails validation reads as `existing === []`, yet
|
|
358
|
+
// `finalEvents` (the frontmatter reconstruction) can itself exceed the cap.
|
|
359
|
+
// Overflow (oldest) rows are dropped from the active ledger but survive
|
|
360
|
+
// both in the timestamped backup (a verbatim copy when the ledger is
|
|
361
|
+
// plaintext, re-encrypted under the backup path's own AAD when it is
|
|
362
|
+
// encrypted so it still decrypts there, #2033) and, for frontmatter-derived
|
|
363
|
+
// rows, in the memory files they were reconstructed from — so a later full
|
|
364
|
+
// rebuild regenerates them.
|
|
365
|
+
if (options.maxLedgerBytes && options.maxLedgerBytes > 0) {
|
|
366
|
+
const bounded = boundLifecycleEventsToByteCap(finalEvents, options.maxLedgerBytes);
|
|
367
|
+
if (bounded.dropped > 0) {
|
|
368
|
+
finalEvents = bounded.kept;
|
|
369
|
+
archivedOverflowRows = bounded.dropped;
|
|
370
|
+
log.warn(
|
|
371
|
+
`lifecycle ledger rebuild bounded to ${options.maxLedgerBytes} bytes: `
|
|
372
|
+
+ `dropped ${bounded.dropped} oldest row(s) from the active ledger `
|
|
373
|
+
+ `(preserved in the backup) to stay under the read/decrypt cap.`,
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Re-assert the lock immediately before the destructive active-ledger
|
|
380
|
+
// rewrite. Everything above (the preserve read, merge, sort, byte-cap
|
|
381
|
+
// bound, and JSON serialize) is CPU-bound and blocks the event loop, so the
|
|
382
|
+
// timer heartbeat inside withHeldFileLock cannot refresh the lock's mtime;
|
|
383
|
+
// a peer that judged the lock stale within the 30s window could have broken
|
|
384
|
+
// it and appended to the current ledger. `lock.refresh()` (a) reports the
|
|
385
|
+
// lock LOST so we ABORT rather than rename our compacted file over that
|
|
386
|
+
// peer's append, and (b) when still held, re-stamps the mtime so the bounded
|
|
387
|
+
// write below cannot itself be judged stale mid-rename (issue #1910/#2033).
|
|
388
|
+
const abortIfLockLost = async (): Promise<void> => {
|
|
389
|
+
if (lock && await lock.refresh()) return;
|
|
390
|
+
throw new Error(
|
|
391
|
+
"lifecycle ledger rebuild aborted: lost the ledger lock during the compaction "
|
|
392
|
+
+ "rewrite (a peer stale-broke it while the event loop was blocked by CPU-bound "
|
|
393
|
+
+ "merge/serialize); refusing to clobber a concurrent append (issue #1910/#2033).",
|
|
394
|
+
);
|
|
395
|
+
};
|
|
396
|
+
if (!dryRun) {
|
|
397
|
+
const payload = finalEvents.map((event) => JSON.stringify(event)).join("\n");
|
|
398
|
+
const content = payload.length > 0 ? `${payload}\n` : "";
|
|
399
|
+
// No-op skip (#2033 thread PRRT_kwDORJXyws6SExst): a preserving rebuild
|
|
400
|
+
// bounds the ACTIVE ledger to the read/decrypt cap, so a VALID ledger that
|
|
401
|
+
// sits above the configured compaction trigger but below the cap would
|
|
402
|
+
// otherwise be rewritten to identical content and re-archived on every
|
|
403
|
+
// maintenance interval — unbounded growth of archive/memory-lifecycle-ledger
|
|
404
|
+
// plus pointless disk/CPU churn. Skip the backup+rewrite when it would
|
|
405
|
+
// change neither the logical (decrypted) content NOR the at-rest format.
|
|
406
|
+
// The raw read here doubles as the source for the encrypted verbatim backup
|
|
407
|
+
// below, so the current ledger is read at most once. An absent ledger reads
|
|
408
|
+
// as ENOENT (a create is always a real change) and any other read/probe
|
|
409
|
+
// error propagates rather than masking a needed rewrite.
|
|
410
|
+
let currentEncrypted = false;
|
|
411
|
+
let priorRawBuffer: Buffer | null = null;
|
|
412
|
+
try {
|
|
413
|
+
currentEncrypted = await probeEncryptedRegularFileHeader(outputPath);
|
|
414
|
+
priorRawBuffer = await storage.readMemoryLifecycleLedgerRawBufferForCompaction();
|
|
415
|
+
} catch (err) {
|
|
416
|
+
if (!isNodeError(err) || err.code !== "ENOENT") throw err;
|
|
417
|
+
}
|
|
418
|
+
// Preserve encryption at rest (#2033). An already-encrypted ledger (or its
|
|
419
|
+
// encrypted backup) MUST be rewritten encrypted even when the
|
|
420
|
+
// `secureStoreEncryptOnWrite` policy is paused — otherwise the compaction
|
|
421
|
+
// silently DOWNGRADES encrypted state to plaintext. Force encryption
|
|
422
|
+
// whenever the current ledger is encrypted and the store is unlocked (a
|
|
423
|
+
// key is available); reaching this point with an encrypted ledger already
|
|
424
|
+
// implies an unlocked store, since the raw read above decrypts and would
|
|
425
|
+
// have thrown under a locked key. A plaintext ledger keeps the ordinary
|
|
426
|
+
// policy (`willEncryptStateWrites`), so existing plaintext behavior holds.
|
|
427
|
+
const forceEncrypt =
|
|
428
|
+
secureRewrite && currentEncrypted && storage.isSecureStoreUnlocked();
|
|
429
|
+
const replacementEncrypted =
|
|
430
|
+
secureRewrite && (storage.willEncryptStateWrites() || forceEncrypt);
|
|
431
|
+
// Compare as buffers, never decoding the raw ledger to one giant string:
|
|
432
|
+
// a multi-hundred-MB decrypted ledger can exceed V8's max string length,
|
|
433
|
+
// so `priorRawBuffer.equals(...)` (byte compare) must be used, NOT
|
|
434
|
+
// `.toString()` (#2033 giant-string invariant). `content` is the freshly
|
|
435
|
+
// serialized replacement, already a string; Buffer.from() reuses it.
|
|
436
|
+
if (
|
|
437
|
+
priorRawBuffer !== null &&
|
|
438
|
+
currentEncrypted === replacementEncrypted &&
|
|
439
|
+
priorRawBuffer.equals(Buffer.from(content, "utf8"))
|
|
440
|
+
) {
|
|
441
|
+
// Nothing to change: leave the active ledger and archive untouched.
|
|
442
|
+
rewritten = false;
|
|
443
|
+
} else {
|
|
444
|
+
const desiredBackup = await backupExistingLedger(options.memoryDir, outputPath, now);
|
|
445
|
+
if (secureRewrite) {
|
|
446
|
+
// Preserve encrypted-at-rest (issue #1910). The BACKUP needs care under
|
|
447
|
+
// secure-store (#2033): when the existing ledger is encrypted, its bytes
|
|
448
|
+
// are path-bound via AAD, so a byte-for-byte copy to the archive path
|
|
449
|
+
// cannot be decrypted there — it would silently orphan the overflow rows
|
|
450
|
+
// a bounded rewrite claims to preserve. Reuse the RAW decrypted ledger
|
|
451
|
+
// content read above (no event parsing, so malformed/truncated/future
|
|
452
|
+
// rows survive exactly as the plaintext verbatim copy keeps them) and
|
|
453
|
+
// re-encrypt it under the backup path's own AAD, yielding a directly
|
|
454
|
+
// decryptable backup that retains every original byte. A PLAINTEXT
|
|
455
|
+
// existing ledger is already readable, so a verbatim copy is correct.
|
|
456
|
+
// Then rewrite the active ledger through the secure writer.
|
|
457
|
+
if (desiredBackup && currentEncrypted) {
|
|
458
|
+
const rawForBackup =
|
|
459
|
+
priorRawBuffer ?? (await storage.readMemoryLifecycleLedgerRawBufferForCompaction());
|
|
460
|
+
await storage.writeMemoryLifecycleLedgerContent(rawForBackup, desiredBackup, forceEncrypt);
|
|
461
|
+
backupPath = desiredBackup;
|
|
462
|
+
} else {
|
|
463
|
+
backupPath = desiredBackup
|
|
464
|
+
? await copyExistingFileToBackup(outputPath, desiredBackup)
|
|
465
|
+
: undefined;
|
|
466
|
+
}
|
|
467
|
+
await abortIfLockLost();
|
|
468
|
+
await storage.writeMemoryLifecycleLedgerContent(content, undefined, forceEncrypt);
|
|
469
|
+
} else {
|
|
470
|
+
await abortIfLockLost();
|
|
471
|
+
backupPath = await writeFileAtomically(outputPath, content, desiredBackup);
|
|
472
|
+
}
|
|
473
|
+
rewritten = true;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
// Write mode holds the ledger lock across the preserve-read and atomic
|
|
478
|
+
// rewrite so a concurrent append lands on the compacted ledger instead of
|
|
479
|
+
// being clobbered. A dry run computes the SAME preserve/merge/byte-cap
|
|
480
|
+
// preview but WITHOUT the lock (read-only, no rewrite), so `rebuiltRows`,
|
|
481
|
+
// `preservedAppendOnlyRows`, and `archivedOverflowRows` report what a --write
|
|
482
|
+
// would apply while never blocking concurrent appends (#2033 Cursor). A dry
|
|
483
|
+
// run with nothing to preserve touches nothing at all.
|
|
123
484
|
if (!dryRun) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
payload.length > 0 ? `${payload}\n` : "",
|
|
129
|
-
backupPath,
|
|
485
|
+
await withHeldFileLock(
|
|
486
|
+
memoryLifecycleLedgerLockPath(outputPath),
|
|
487
|
+
{ staleMs: MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS, ...options.lockOptions },
|
|
488
|
+
runLedgerCriticalSection,
|
|
130
489
|
);
|
|
490
|
+
} else if (options.preserveExistingEvents) {
|
|
491
|
+
await runLedgerCriticalSection(true, null);
|
|
131
492
|
}
|
|
132
493
|
|
|
133
494
|
return {
|
|
134
495
|
dryRun,
|
|
135
496
|
scannedMemories: allMemories.length,
|
|
136
|
-
rebuiltRows:
|
|
497
|
+
rebuiltRows: finalEvents.length,
|
|
137
498
|
outputPath,
|
|
138
499
|
backupPath,
|
|
139
500
|
skippedBlankIdMemories,
|
|
140
501
|
skippedDuplicateEvents,
|
|
502
|
+
preservedAppendOnlyRows,
|
|
503
|
+
archivedOverflowRows,
|
|
504
|
+
rewritten,
|
|
141
505
|
};
|
|
142
506
|
}
|
package/src/memory-cache.ts
CHANGED
|
@@ -284,6 +284,19 @@ export function setCachedQmdSearch(cacheKey: string, results: unknown[]): void {
|
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
+
/**
|
|
288
|
+
* Mutation scopes (issue #1904). A cache layer declares (via `evictOn`) which
|
|
289
|
+
* of these mutation kinds evict it, so the invalidation chokepoint can clear
|
|
290
|
+
* only the layers a given write actually affects instead of nuking every
|
|
291
|
+
* layer on every write (the permanently-cold-cache regression #1904 fixes).
|
|
292
|
+
*/
|
|
293
|
+
export type MemoryMutationScope =
|
|
294
|
+
| "memory-create" // a new memory doc added; no existing doc's recall-visibility changes
|
|
295
|
+
| "memory-mutate" // existing doc changed/moved/removed/status-changed (update, supersede,
|
|
296
|
+
// archive, invalidate, frontmatter, cold-tier change, bulk delete)
|
|
297
|
+
| "entity-write" // an entity file changed
|
|
298
|
+
| "secure-key-change"; // encryption key rotated; everything is now unreadable → evict all
|
|
299
|
+
|
|
287
300
|
/**
|
|
288
301
|
* Cache-layer registry (issue #1535).
|
|
289
302
|
*
|
|
@@ -305,6 +318,11 @@ export interface MemoryCacheLayer {
|
|
|
305
318
|
* the simple-and-correct choice — these caches are re-warmable
|
|
306
319
|
* (issue #1535, implementation guide option (b)). */
|
|
307
320
|
readonly scope: "dir" | "global";
|
|
321
|
+
/** Which mutation scopes evict this layer (issue #1904). A `memory-create`
|
|
322
|
+
* only refreshes the full-memory-list views (hot + derived episode/rule); a
|
|
323
|
+
* `memory-mutate`/`entity-write`/`secure-key-change` evicts every layer whose
|
|
324
|
+
* content it can affect. Adding a layer REQUIRES declaring this. */
|
|
325
|
+
readonly evictOn: Partial<Record<MemoryMutationScope, true>>;
|
|
308
326
|
/** Evict entries for baseDir ("dir" scope) or everything ("global" scope). */
|
|
309
327
|
readonly invalidateForDir: (baseDir: string) => void;
|
|
310
328
|
/** Evict every entry across all dirs. */
|
|
@@ -318,6 +336,7 @@ export const ALL_CACHE_LAYERS: readonly MemoryCacheLayer[] = [
|
|
|
318
336
|
{
|
|
319
337
|
name: "hot-memories",
|
|
320
338
|
scope: "dir",
|
|
339
|
+
evictOn: { "memory-create": true, "memory-mutate": true, "secure-key-change": true },
|
|
321
340
|
invalidateForDir: (baseDir) => void hotCacheByDir.delete(baseDir),
|
|
322
341
|
clearAll: () => hotCacheByDir.clear(),
|
|
323
342
|
hasEntriesFor: (baseDir) => hotCacheByDir.has(baseDir),
|
|
@@ -325,6 +344,7 @@ export const ALL_CACHE_LAYERS: readonly MemoryCacheLayer[] = [
|
|
|
325
344
|
{
|
|
326
345
|
name: "archive-memories",
|
|
327
346
|
scope: "dir",
|
|
347
|
+
evictOn: { "memory-mutate": true, "secure-key-change": true },
|
|
328
348
|
invalidateForDir: (baseDir) => void archiveCacheByDir.delete(baseDir),
|
|
329
349
|
clearAll: () => archiveCacheByDir.clear(),
|
|
330
350
|
hasEntriesFor: (baseDir) => archiveCacheByDir.has(baseDir),
|
|
@@ -332,6 +352,7 @@ export const ALL_CACHE_LAYERS: readonly MemoryCacheLayer[] = [
|
|
|
332
352
|
{
|
|
333
353
|
name: "entities",
|
|
334
354
|
scope: "dir",
|
|
355
|
+
evictOn: { "entity-write": true, "secure-key-change": true },
|
|
335
356
|
invalidateForDir: (baseDir) => invalidateCachedEntities(baseDir),
|
|
336
357
|
clearAll: () => entityCacheByDir.clear(),
|
|
337
358
|
hasEntriesFor: (baseDir) => {
|
|
@@ -345,6 +366,7 @@ export const ALL_CACHE_LAYERS: readonly MemoryCacheLayer[] = [
|
|
|
345
366
|
{
|
|
346
367
|
name: "derived-episode-map",
|
|
347
368
|
scope: "dir",
|
|
369
|
+
evictOn: { "memory-create": true, "memory-mutate": true, "secure-key-change": true },
|
|
348
370
|
invalidateForDir: (baseDir) => void episodeMapByDir.delete(baseDir),
|
|
349
371
|
clearAll: () => episodeMapByDir.clear(),
|
|
350
372
|
hasEntriesFor: (baseDir) => episodeMapByDir.has(baseDir),
|
|
@@ -352,6 +374,7 @@ export const ALL_CACHE_LAYERS: readonly MemoryCacheLayer[] = [
|
|
|
352
374
|
{
|
|
353
375
|
name: "derived-rule-memories",
|
|
354
376
|
scope: "dir",
|
|
377
|
+
evictOn: { "memory-create": true, "memory-mutate": true, "secure-key-change": true },
|
|
355
378
|
invalidateForDir: (baseDir) => void ruleMemoriesByDir.delete(baseDir),
|
|
356
379
|
clearAll: () => ruleMemoriesByDir.clear(),
|
|
357
380
|
hasEntriesFor: (baseDir) => ruleMemoriesByDir.has(baseDir),
|
|
@@ -359,6 +382,7 @@ export const ALL_CACHE_LAYERS: readonly MemoryCacheLayer[] = [
|
|
|
359
382
|
{
|
|
360
383
|
name: "qmd-search",
|
|
361
384
|
scope: "global",
|
|
385
|
+
evictOn: { "memory-mutate": true, "entity-write": true, "secure-key-change": true },
|
|
362
386
|
invalidateForDir: () => qmdSearchCache.clear(),
|
|
363
387
|
clearAll: () => qmdSearchCache.clear(),
|
|
364
388
|
hasEntriesFor: () => qmdSearchCache.size > 0,
|
|
@@ -366,6 +390,7 @@ export const ALL_CACHE_LAYERS: readonly MemoryCacheLayer[] = [
|
|
|
366
390
|
{
|
|
367
391
|
name: "qmd-recall",
|
|
368
392
|
scope: "global",
|
|
393
|
+
evictOn: { "memory-mutate": true, "entity-write": true, "secure-key-change": true },
|
|
369
394
|
invalidateForDir: () => clearQmdRecallCache(),
|
|
370
395
|
clearAll: () => clearQmdRecallCache(),
|
|
371
396
|
hasEntriesFor: () => qmdRecallCacheSize() > 0,
|
|
@@ -389,6 +414,37 @@ export function invalidateAllForDir(baseDir: string): void {
|
|
|
389
414
|
}
|
|
390
415
|
}
|
|
391
416
|
|
|
417
|
+
/**
|
|
418
|
+
* Scope-aware invalidation chokepoint (issue #1904). Evicts only the layers
|
|
419
|
+
* whose `evictOn` includes `scope`, so the highest-frequency write
|
|
420
|
+
* (`memory-create`, fired continuously by extraction) stops nuking the QMD
|
|
421
|
+
* result caches and the version-keyed entity cache it cannot affect. This is
|
|
422
|
+
* the single scoped entry point — like `invalidateAllForDir`, it iterates the
|
|
423
|
+
* `ALL_CACHE_LAYERS` registry rather than clearing any layer ad hoc, so the
|
|
424
|
+
* single-chokepoint invariant (#1535) holds: a new layer only participates by
|
|
425
|
+
* declaring `evictOn`.
|
|
426
|
+
*/
|
|
427
|
+
export function invalidateForScope(baseDir: string, scope: MemoryMutationScope): void {
|
|
428
|
+
for (const layer of ALL_CACHE_LAYERS) {
|
|
429
|
+
if (layer.evictOn[scope]) layer.invalidateForDir(baseDir);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Companion to {@link invalidateForScope} for the single-file write fast path
|
|
435
|
+
* (issue #1902 + #1904): it patches the hot-memories entry in place and
|
|
436
|
+
* re-keys it, so this evicts every OTHER layer the scope would clear but leaves
|
|
437
|
+
* hot-memories alone. A `memory-create` thus evicts only the derived
|
|
438
|
+
* episode/rule views (hot patched, QMD/entities/archive kept warm), which is
|
|
439
|
+
* the whole point of #1904 — a create must not evict the QMD result caches.
|
|
440
|
+
*/
|
|
441
|
+
export function invalidateForScopeExceptHot(baseDir: string, scope: MemoryMutationScope): void {
|
|
442
|
+
for (const layer of ALL_CACHE_LAYERS) {
|
|
443
|
+
if (layer.name === "hot-memories") continue;
|
|
444
|
+
if (layer.evictOn[scope]) layer.invalidateForDir(baseDir);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
392
448
|
/**
|
|
393
449
|
* Invalidate every cache layer for `baseDir` EXCEPT the hot-memories layer
|
|
394
450
|
* (issue #1902). Single-file write paths use this instead of
|
|
@@ -429,6 +485,20 @@ export function clearMemoryCache(baseDir?: string): void {
|
|
|
429
485
|
}
|
|
430
486
|
}
|
|
431
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Clear ONLY the two global QMD result caches (qmd-search + qmd-recall), leaving
|
|
490
|
+
* every dir-scoped layer (hot/archive/entities/derived) untouched. Called after
|
|
491
|
+
* a successful QMD maintenance update+embed (#1904, Codex): a newly-persisted
|
|
492
|
+
* fact becomes searchable at that moment, so any cached pre-index recall/search
|
|
493
|
+
* bundle is now stale and must not be served. This lets the create path keep the
|
|
494
|
+
* QMD caches warm during index lag (perf win) while guaranteeing invalidation
|
|
495
|
+
* the moment the fact is actually indexed — no extended stale window.
|
|
496
|
+
*/
|
|
497
|
+
export function clearQmdResultCaches(): void {
|
|
498
|
+
qmdSearchCache.clear();
|
|
499
|
+
clearQmdRecallCache();
|
|
500
|
+
}
|
|
501
|
+
|
|
432
502
|
export function getMemoryCacheStats(baseDir: string): {
|
|
433
503
|
hotSize: number;
|
|
434
504
|
archiveSize: number;
|