@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
package/src/graph.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* All writes are fail-open: errors are caught/logged, never thrown.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { appendFile, mkdir, readFile } from "node:fs/promises";
|
|
13
|
+
import { appendFile, mkdir, readFile, stat } from "node:fs/promises";
|
|
14
14
|
import * as path from "node:path";
|
|
15
15
|
|
|
16
16
|
import { readEdgeConfidence } from "./graph-edge-reinforcement.js";
|
|
@@ -59,6 +59,18 @@ export interface GraphConfig {
|
|
|
59
59
|
* and return raw BFS scores. Default 8.
|
|
60
60
|
*/
|
|
61
61
|
graphTraversalPageRankIterations: number;
|
|
62
|
+
/**
|
|
63
|
+
* Issue #1904 — incremental GraphIndex edge cache. When true (the default,
|
|
64
|
+
* and the value when omitted), a single-writer edge append is pushed into the
|
|
65
|
+
* warm edge cache in place (revalidated by file size for cross-process
|
|
66
|
+
* coherence) instead of nulling the cache and paying a full 6 MB re-read +
|
|
67
|
+
* parse on the next traversal. Set false to restore the pre-#1904
|
|
68
|
+
* null-on-every-write behavior. Optional here (unlike the required
|
|
69
|
+
* PluginConfig field parseConfig always sets) so GraphConfig can still be
|
|
70
|
+
* constructed directly with a partial config; only an explicit `false` opts
|
|
71
|
+
* out, so an omitted field keeps the incremental default.
|
|
72
|
+
*/
|
|
73
|
+
graphEdgeCacheIncrementalEnabled?: boolean;
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
/** Default minimum edge confidence required for traversal (issue #681 PR 3/3). */
|
|
@@ -370,6 +382,18 @@ export function detectCausalPhrase(text: string): string | null {
|
|
|
370
382
|
* // After each memory write:
|
|
371
383
|
* await this.graphIndex.onMemoryWritten(memoryPath, frontmatter, threadId, recentInThread);
|
|
372
384
|
*/
|
|
385
|
+
/**
|
|
386
|
+
* Identity of one graph JSONL file used to validate the incremental edge cache
|
|
387
|
+
* (issue #1904). An absent file (ENOENT) is recorded as the all-zero sentinel
|
|
388
|
+
* `{ size: 0, mtimeMs: 0, ino: 0 }` so a later peer creation (ino becomes
|
|
389
|
+
* non-zero) is detected as a change.
|
|
390
|
+
*/
|
|
391
|
+
interface GraphFileMeta {
|
|
392
|
+
size: number;
|
|
393
|
+
mtimeMs: number;
|
|
394
|
+
ino: number;
|
|
395
|
+
}
|
|
396
|
+
|
|
373
397
|
export class GraphIndex {
|
|
374
398
|
private readonly memoryDir: string;
|
|
375
399
|
private readonly cfg: GraphConfig;
|
|
@@ -378,7 +402,20 @@ export class GraphIndex {
|
|
|
378
402
|
// file read + JSON parse takes 2-4 s per call. This instance-level cache
|
|
379
403
|
// eliminates that overhead on every spreadingActivation() call; it is
|
|
380
404
|
// invalidated (set to null) in onMemoryWritten() so new edges appear promptly.
|
|
381
|
-
private edgeCache: {
|
|
405
|
+
private edgeCache: {
|
|
406
|
+
allEdges: GraphEdge[];
|
|
407
|
+
loadedAt: number;
|
|
408
|
+
// Per-file identity of each enabled graph file observed at load (issue
|
|
409
|
+
// #1904). An incremental push is trusted only when every file's identity is
|
|
410
|
+
// explained entirely by OUR own append: size grows by exactly the bytes we
|
|
411
|
+
// appended and the inode is unchanged (a local append keeps the inode; an
|
|
412
|
+
// external atomic temp+rename rewrite — e.g. the edge-decay job — changes
|
|
413
|
+
// it). Untouched files must match size AND mtime AND inode exactly. This
|
|
414
|
+
// closes the size-only holes Codex flagged: a peer append racing cache
|
|
415
|
+
// construction, and an equal-length atomic rewrite (e.g. confidence
|
|
416
|
+
// 0.9->0.8) that preserves byte length. Any divergence forces a full reload.
|
|
417
|
+
meta: Partial<Record<GraphType, GraphFileMeta>>;
|
|
418
|
+
} | null = null;
|
|
382
419
|
private static readonly EDGE_CACHE_TTL_MS = 300_000; // 5 minutes
|
|
383
420
|
|
|
384
421
|
constructor(memoryDir: string, cfg: GraphConfig) {
|
|
@@ -396,15 +433,120 @@ export class GraphIndex {
|
|
|
396
433
|
if (this.edgeCache && Date.now() - this.edgeCache.loadedAt < GraphIndex.EDGE_CACHE_TTL_MS) {
|
|
397
434
|
return this.edgeCache.allEdges;
|
|
398
435
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
436
|
+
// Consistent snapshot (issue #1904, Codex): capture file identity BEFORE and
|
|
437
|
+
// AFTER reading edges and retry if it changed, so `allEdges` and the recorded
|
|
438
|
+
// `meta` baseline reflect the SAME on-disk state. Without this a peer append
|
|
439
|
+
// landing mid-read would leave the cache holding edges that exclude the peer
|
|
440
|
+
// edge while the baseline already counts its bytes — a later local append
|
|
441
|
+
// would then pass the size-delta check and silently omit the peer edge.
|
|
442
|
+
let allEdges: GraphEdge[] = [];
|
|
443
|
+
let meta = await this.readEnabledGraphFileMeta();
|
|
444
|
+
let stable = false;
|
|
445
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
446
|
+
const before = meta;
|
|
447
|
+
allEdges = await readAllEdges(this.memoryDir, {
|
|
448
|
+
entityGraph: this.cfg.entityGraphEnabled,
|
|
449
|
+
timeGraph: this.cfg.timeGraphEnabled,
|
|
450
|
+
causalGraph: this.cfg.causalGraphEnabled,
|
|
451
|
+
});
|
|
452
|
+
meta = await this.readEnabledGraphFileMeta();
|
|
453
|
+
if (this.graphFileMetaEqual(before, meta)) {
|
|
454
|
+
stable = true;
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
// A write landed during the read; the just-captured `meta` is the new
|
|
458
|
+
// baseline for the next attempt's before-snapshot.
|
|
459
|
+
}
|
|
460
|
+
if (stable) {
|
|
461
|
+
this.edgeCache = { allEdges, loadedAt: Date.now(), meta };
|
|
462
|
+
} else {
|
|
463
|
+
// Contended: a peer kept writing across every attempt, so the final
|
|
464
|
+
// allEdges/meta pair is not guaranteed consistent. Serve THIS read's edges
|
|
465
|
+
// (best effort) but do NOT poison the cache — leave it null so the next
|
|
466
|
+
// call re-reads, instead of installing a baseline that could hide a peer
|
|
467
|
+
// edge for the TTL (Codex).
|
|
468
|
+
this.edgeCache = null;
|
|
469
|
+
}
|
|
405
470
|
return allEdges;
|
|
406
471
|
}
|
|
407
472
|
|
|
473
|
+
/**
|
|
474
|
+
* Identity ({ size, mtimeMs, ino }) of each ENABLED graph file (issue #1904).
|
|
475
|
+
* Missing files (ENOENT) and any stat error map to the all-zero sentinel so
|
|
476
|
+
* the baseline is fail-open: a later revalidation sees a mismatch (or a peer
|
|
477
|
+
* creation flipping ino from 0 to non-zero) and forces a full reload rather
|
|
478
|
+
* than trusting a stale incremental push.
|
|
479
|
+
*/
|
|
480
|
+
private async readEnabledGraphFileMeta(): Promise<Partial<Record<GraphType, GraphFileMeta>>> {
|
|
481
|
+
const enabled: GraphType[] = [];
|
|
482
|
+
if (this.cfg.entityGraphEnabled) enabled.push("entity");
|
|
483
|
+
if (this.cfg.timeGraphEnabled) enabled.push("time");
|
|
484
|
+
if (this.cfg.causalGraphEnabled) enabled.push("causal");
|
|
485
|
+
const meta: Partial<Record<GraphType, GraphFileMeta>> = {};
|
|
486
|
+
for (const type of enabled) {
|
|
487
|
+
try {
|
|
488
|
+
const st = await stat(graphFilePath(this.memoryDir, type));
|
|
489
|
+
meta[type] = { size: st.size, mtimeMs: st.mtimeMs, ino: Number(st.ino) };
|
|
490
|
+
} catch {
|
|
491
|
+
meta[type] = { size: 0, mtimeMs: 0, ino: 0 };
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return meta;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/** True iff both metadata maps carry identical identity for every key. */
|
|
498
|
+
private graphFileMetaEqual(
|
|
499
|
+
a: Partial<Record<GraphType, GraphFileMeta>>,
|
|
500
|
+
b: Partial<Record<GraphType, GraphFileMeta>>,
|
|
501
|
+
): boolean {
|
|
502
|
+
const types: GraphType[] = ["entity", "time", "causal"];
|
|
503
|
+
for (const type of types) {
|
|
504
|
+
const x = a[type];
|
|
505
|
+
const y = b[type];
|
|
506
|
+
if (!x && !y) continue;
|
|
507
|
+
if (!x || !y) return false;
|
|
508
|
+
if (x.size !== y.size || x.mtimeMs !== y.mtimeMs || x.ino !== y.ino) return false;
|
|
509
|
+
}
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Re-stat every graph file whose identity the cache just committed and return
|
|
515
|
+
* false if any has moved since (issue #1904, Codex). Closes the validation→
|
|
516
|
+
* in-place-push TOCTOU window: a peer process (concurrent CLI / daemon /
|
|
517
|
+
* decay job) can append between edgeFilesUnchangedExceptOurAppends()'s final
|
|
518
|
+
* stat and the allEdges.push(...). Without this re-check the cache would be
|
|
519
|
+
* accepted with identity predating the peer write and miss the peer edge for
|
|
520
|
+
* the TTL. A residual infinitesimal window (peer writes during this re-stat)
|
|
521
|
+
* remains and is TTL-bounded.
|
|
522
|
+
*/
|
|
523
|
+
private async edgeCacheIdentityUnchangedSinceCommit(): Promise<boolean> {
|
|
524
|
+
if (!this.edgeCache) return false;
|
|
525
|
+
for (const type of Object.keys(this.edgeCache.meta) as GraphType[]) {
|
|
526
|
+
const committed = this.edgeCache.meta[type];
|
|
527
|
+
if (!committed) continue;
|
|
528
|
+
let cur: GraphFileMeta;
|
|
529
|
+
try {
|
|
530
|
+
const st = await stat(graphFilePath(this.memoryDir, type));
|
|
531
|
+
cur = { size: st.size, mtimeMs: st.mtimeMs, ino: Number(st.ino) };
|
|
532
|
+
} catch (err) {
|
|
533
|
+
if ((err as NodeJS.ErrnoException)?.code === "ENOENT") {
|
|
534
|
+
cur = { size: 0, mtimeMs: 0, ino: 0 };
|
|
535
|
+
} else {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (
|
|
540
|
+
cur.size !== committed.size ||
|
|
541
|
+
cur.mtimeMs !== committed.mtimeMs ||
|
|
542
|
+
cur.ino !== committed.ino
|
|
543
|
+
) {
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return true;
|
|
548
|
+
}
|
|
549
|
+
|
|
408
550
|
/**
|
|
409
551
|
* Called after a memory is written to disk.
|
|
410
552
|
*
|
|
@@ -444,20 +586,25 @@ export class GraphIndex {
|
|
|
444
586
|
const timeOn = g ? g.timeGraph : this.cfg.timeGraphEnabled;
|
|
445
587
|
const causalOn = g ? g.causalGraph : this.cfg.causalGraphEnabled;
|
|
446
588
|
const ts = new Date().toISOString();
|
|
589
|
+
// Collect the edges appended this call so a coherent single-writer push can
|
|
590
|
+
// extend the warm edge cache in place instead of nulling it (issue #1904).
|
|
591
|
+
const appended: GraphEdge[] = [];
|
|
447
592
|
|
|
448
593
|
try {
|
|
449
594
|
// Entity graph
|
|
450
595
|
if (entityOn && opts.entityRef && opts.entitySiblings?.length) {
|
|
451
596
|
const siblings = opts.entitySiblings.slice(0, this.cfg.maxEntityGraphEdgesPerMemory);
|
|
452
597
|
for (const sibling of siblings) {
|
|
453
|
-
|
|
598
|
+
const edge: GraphEdge = {
|
|
454
599
|
from: opts.memoryPath,
|
|
455
600
|
to: sibling,
|
|
456
601
|
type: "entity",
|
|
457
602
|
weight: 1.0,
|
|
458
603
|
label: opts.entityRef,
|
|
459
604
|
ts,
|
|
460
|
-
}
|
|
605
|
+
};
|
|
606
|
+
appended.push(edge);
|
|
607
|
+
await appendEdge(this.memoryDir, edge);
|
|
461
608
|
}
|
|
462
609
|
}
|
|
463
610
|
|
|
@@ -465,14 +612,16 @@ export class GraphIndex {
|
|
|
465
612
|
if (timeOn && opts.threadId && opts.recentInThread?.length) {
|
|
466
613
|
const predecessor = opts.recentInThread[opts.recentInThread.length - 1];
|
|
467
614
|
if (predecessor && predecessor !== opts.memoryPath) {
|
|
468
|
-
|
|
615
|
+
const edge: GraphEdge = {
|
|
469
616
|
from: predecessor,
|
|
470
617
|
to: opts.memoryPath,
|
|
471
618
|
type: "time",
|
|
472
619
|
weight: 1.0,
|
|
473
620
|
label: opts.threadId,
|
|
474
621
|
ts,
|
|
475
|
-
}
|
|
622
|
+
};
|
|
623
|
+
appended.push(edge);
|
|
624
|
+
await appendEdge(this.memoryDir, edge);
|
|
476
625
|
}
|
|
477
626
|
}
|
|
478
627
|
|
|
@@ -480,14 +629,16 @@ export class GraphIndex {
|
|
|
480
629
|
if (causalOn && opts.causalPredecessor) {
|
|
481
630
|
const phrase = detectCausalPhrase(opts.content);
|
|
482
631
|
if (phrase) {
|
|
483
|
-
|
|
632
|
+
const edge: GraphEdge = {
|
|
484
633
|
from: opts.causalPredecessor,
|
|
485
634
|
to: opts.memoryPath,
|
|
486
635
|
type: "causal",
|
|
487
636
|
weight: 1.0,
|
|
488
637
|
label: phrase,
|
|
489
638
|
ts,
|
|
490
|
-
}
|
|
639
|
+
};
|
|
640
|
+
appended.push(edge);
|
|
641
|
+
await appendEdge(this.memoryDir, edge);
|
|
491
642
|
}
|
|
492
643
|
}
|
|
493
644
|
} catch (err) {
|
|
@@ -495,10 +646,116 @@ export class GraphIndex {
|
|
|
495
646
|
const { log } = await import("./logger.js");
|
|
496
647
|
log.warn(`[graph] onMemoryWritten error: ${err}`);
|
|
497
648
|
} finally {
|
|
498
|
-
//
|
|
499
|
-
//
|
|
500
|
-
this.edgeCache
|
|
649
|
+
// Edge-cache coherence (issue #1904). Legacy behavior nulled the cache on
|
|
650
|
+
// every write, paying a 2-4 s full re-read + parse on the next traversal.
|
|
651
|
+
if (!this.edgeCache || Date.now() - this.edgeCache.loadedAt >= GraphIndex.EDGE_CACHE_TTL_MS) {
|
|
652
|
+
// Nothing warm, or the entry is past its 5-min TTL backstop — reload.
|
|
653
|
+
this.edgeCache = null;
|
|
654
|
+
} else if (this.cfg.graphEdgeCacheIncrementalEnabled === false) {
|
|
655
|
+
// Rollback lever: restore the pre-#1904 null-on-every-write behavior.
|
|
656
|
+
this.edgeCache = null;
|
|
657
|
+
} else {
|
|
658
|
+
// Trust an in-place push ONLY when WE are the sole writer since load:
|
|
659
|
+
// every enabled graph file's on-disk size must equal our baseline plus
|
|
660
|
+
// exactly the bytes we appended to it. A divergence means a peer process
|
|
661
|
+
// (backup daemon / CLI / decay job) also wrote — force a full reload for
|
|
662
|
+
// cross-process coherence. Any stat error fails open to a full reload.
|
|
663
|
+
try {
|
|
664
|
+
if (await this.edgeFilesUnchangedExceptOurAppends(appended)) {
|
|
665
|
+
if (appended.length > 0) {
|
|
666
|
+
this.edgeCache.allEdges.push(...appended);
|
|
667
|
+
// Close the validation→push TOCTOU window (#1904, Codex): a peer
|
|
668
|
+
// process can append between the validation stat above and this
|
|
669
|
+
// in-place push. Re-verify every committed identity; if any file
|
|
670
|
+
// moved, the cache would miss the peer edge for the TTL, so null
|
|
671
|
+
// it and let the next traversal reload. (Skipped when this call
|
|
672
|
+
// pushed nothing — no new window was opened, and the validation
|
|
673
|
+
// already confirmed no peer wrote.)
|
|
674
|
+
if (this.edgeCache && !(await this.edgeCacheIdentityUnchangedSinceCommit())) {
|
|
675
|
+
this.edgeCache = null;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
} else {
|
|
679
|
+
this.edgeCache = null;
|
|
680
|
+
}
|
|
681
|
+
} catch {
|
|
682
|
+
this.edgeCache = null;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Cross-process coherence check for the incremental edge cache (issue #1904).
|
|
690
|
+
*
|
|
691
|
+
* Returns true iff every ENABLED graph file's current identity is explained
|
|
692
|
+
* ENTIRELY by THIS call's own append — no other process wrote to any graph
|
|
693
|
+
* file since load. Per file:
|
|
694
|
+
* - inode must be unchanged. A local append (`appendFile`) keeps the inode;
|
|
695
|
+
* an external atomic temp+rename rewrite (e.g. the edge-decay job) changes
|
|
696
|
+
* it, so an inode change — even one that preserves byte length, such as
|
|
697
|
+
* decaying confidence 0.9->0.8 — forces a reload (Codex).
|
|
698
|
+
* - a file WE appended to (delta > 0): size must equal baseline + our exact
|
|
699
|
+
* appended bytes. If it was absent at load (sentinel ino 0), our append
|
|
700
|
+
* created it, so we accept size === delta and adopt the new identity.
|
|
701
|
+
* - a file we did NOT touch (delta 0): size AND mtime must be unchanged, so
|
|
702
|
+
* an in-place equal-length rewrite (mtime bump) or a peer append (size
|
|
703
|
+
* bump) both force a reload.
|
|
704
|
+
* On success it commits the new identity baseline so the next append
|
|
705
|
+
* revalidates against post-this-write truth. Fail-open: an unreadable file
|
|
706
|
+
* (non-ENOENT) returns false, forcing a full reload.
|
|
707
|
+
*/
|
|
708
|
+
private async edgeFilesUnchangedExceptOurAppends(appended: GraphEdge[]): Promise<boolean> {
|
|
709
|
+
if (!this.edgeCache) return false;
|
|
710
|
+
const expectedDelta: Partial<Record<GraphType, number>> = {};
|
|
711
|
+
for (const edge of appended) {
|
|
712
|
+
const bytes = Buffer.byteLength(`${JSON.stringify(edge)}\n`, "utf8");
|
|
713
|
+
expectedDelta[edge.type] = (expectedDelta[edge.type] ?? 0) + bytes;
|
|
714
|
+
}
|
|
715
|
+
const enabled: GraphType[] = [];
|
|
716
|
+
if (this.cfg.entityGraphEnabled) enabled.push("entity");
|
|
717
|
+
if (this.cfg.timeGraphEnabled) enabled.push("time");
|
|
718
|
+
if (this.cfg.causalGraphEnabled) enabled.push("causal");
|
|
719
|
+
const observed: Partial<Record<GraphType, GraphFileMeta>> = {};
|
|
720
|
+
for (const type of enabled) {
|
|
721
|
+
let cur: GraphFileMeta;
|
|
722
|
+
try {
|
|
723
|
+
const st = await stat(graphFilePath(this.memoryDir, type));
|
|
724
|
+
cur = { size: st.size, mtimeMs: st.mtimeMs, ino: Number(st.ino) };
|
|
725
|
+
} catch (err) {
|
|
726
|
+
// An absent graph file (ENOENT) is the normal partially-populated state
|
|
727
|
+
// (e.g. entity edges written before any causal edge): treat it as the
|
|
728
|
+
// all-zero sentinel so the incremental cache stays warm. Only a genuine
|
|
729
|
+
// stat failure forces a full reload (#1904, Codex).
|
|
730
|
+
if ((err as NodeJS.ErrnoException)?.code === "ENOENT") {
|
|
731
|
+
cur = { size: 0, mtimeMs: 0, ino: 0 };
|
|
732
|
+
} else {
|
|
733
|
+
return false;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
const base = this.edgeCache.meta[type] ?? { size: 0, mtimeMs: 0, ino: 0 };
|
|
737
|
+
const delta = expectedDelta[type] ?? 0;
|
|
738
|
+
if (delta > 0) {
|
|
739
|
+
if (base.ino === 0) {
|
|
740
|
+
// File was absent at load; our append created it. Accept iff its whole
|
|
741
|
+
// size is exactly our appended bytes (nothing else wrote it).
|
|
742
|
+
if (cur.ino === 0 || cur.size !== delta) return false;
|
|
743
|
+
} else {
|
|
744
|
+
// Existing file: our append keeps the inode and grows size by exactly
|
|
745
|
+
// our bytes. An atomic rewrite (ino change) or a peer append (size
|
|
746
|
+
// mismatch) both fail here.
|
|
747
|
+
if (cur.ino !== base.ino || cur.size !== base.size + delta) return false;
|
|
748
|
+
}
|
|
749
|
+
} else {
|
|
750
|
+
// Untouched file: identity must be byte-for-byte unchanged.
|
|
751
|
+
if (cur.ino !== base.ino || cur.size !== base.size || cur.mtimeMs !== base.mtimeMs) {
|
|
752
|
+
return false;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
observed[type] = cur;
|
|
501
756
|
}
|
|
757
|
+
this.edgeCache.meta = observed;
|
|
758
|
+
return true;
|
|
502
759
|
}
|
|
503
760
|
|
|
504
761
|
/**
|
package/src/index.ts
CHANGED
|
@@ -111,6 +111,26 @@ export {
|
|
|
111
111
|
serializeEntityFile,
|
|
112
112
|
type MemoryWriteResult,
|
|
113
113
|
} from "./storage.js";
|
|
114
|
+
export {
|
|
115
|
+
composeMemoryEnvelope,
|
|
116
|
+
buildAccessWriteRequestFingerprint,
|
|
117
|
+
buildObserveRequestFingerprint,
|
|
118
|
+
buildWriteIdempotencyPayload,
|
|
119
|
+
isSealedMemoryEnvelope,
|
|
120
|
+
sealedWriteToLegacyArgs,
|
|
121
|
+
TAG_LIMITS,
|
|
122
|
+
STRUCTURED_ATTRIBUTE_LIMITS,
|
|
123
|
+
WRITE_FINGERPRINT_FIELDS,
|
|
124
|
+
FINGERPRINT_EXEMPT_FIELDS,
|
|
125
|
+
FINGERPRINT_SCOPE_FIELDS,
|
|
126
|
+
type SealedMemoryEnvelope,
|
|
127
|
+
type MemoryWriteInput,
|
|
128
|
+
type WriteContext,
|
|
129
|
+
type FingerprintScope,
|
|
130
|
+
type AccessWriteFingerprintParts,
|
|
131
|
+
type ObserveFingerprintParts,
|
|
132
|
+
type ComposeEnvelopeOptions,
|
|
133
|
+
} from "./write-envelope.js";
|
|
114
134
|
export {
|
|
115
135
|
getHostEmbeddingProvider,
|
|
116
136
|
normalizeHostEmbeddingVector,
|
|
@@ -329,7 +349,7 @@ export { MeilisearchBackend } from "./search/meilisearch-backend.js";
|
|
|
329
349
|
// ---------------------------------------------------------------------------
|
|
330
350
|
|
|
331
351
|
export { buildEntityRecallSection } from "./entity-retrieval.js";
|
|
332
|
-
export { resolvePrincipal } from "./namespaces/principal.js";
|
|
352
|
+
export { isNamespacePolicyCovered, resolvePrincipal } from "./namespaces/principal.js";
|
|
333
353
|
export {
|
|
334
354
|
NamespaceCatalog,
|
|
335
355
|
type NamespaceRecord,
|
|
@@ -810,7 +830,7 @@ export {
|
|
|
810
830
|
// ---------------------------------------------------------------------------
|
|
811
831
|
// Offline Sync
|
|
812
832
|
// ---------------------------------------------------------------------------
|
|
813
|
-
|
|
833
|
+
export { drainPendingImpressionsForOfflineSync, drainPendingLifecycleForOfflineSync } from "./offline-sync-impression-drain.js";
|
|
814
834
|
export {
|
|
815
835
|
OFFLINE_SYNC_APPLY_MAX_BODY_BYTES,
|
|
816
836
|
OFFLINE_SYNC_CHANGESET_FORMAT,
|
package/src/local-llm.ts
CHANGED
|
@@ -858,11 +858,9 @@ export class LocalLlmClient {
|
|
|
858
858
|
});
|
|
859
859
|
}
|
|
860
860
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
this.requestQueues.background.length > 0
|
|
865
|
-
);
|
|
861
|
+
/** True when a background-priority request occupies or awaits this client's local lane (issue #2011). */
|
|
862
|
+
isBackgroundLaneContended(): boolean {
|
|
863
|
+
return this.queueProcessing.has("background") || this.requestQueues.background.length > 0;
|
|
866
864
|
}
|
|
867
865
|
|
|
868
866
|
private dequeueQueuedRequest(priority: LocalLlmRequestPriority): LocalLlmQueuedRequest | null {
|
|
@@ -924,7 +922,7 @@ export class LocalLlmClient {
|
|
|
924
922
|
next.resolve(result);
|
|
925
923
|
} finally {
|
|
926
924
|
this.queueProcessing.delete(next.priority);
|
|
927
|
-
if (this.
|
|
925
|
+
if (this.requestQueues["recall-critical"].length > 0 || this.requestQueues.background.length > 0) {
|
|
928
926
|
this.scheduleQueueDrain();
|
|
929
927
|
}
|
|
930
928
|
}
|
package/src/logger.ts
CHANGED
|
@@ -60,6 +60,22 @@ export function initLogger(backend?: LoggerBackend, debug?: boolean, options?: L
|
|
|
60
60
|
_clock = options?.clock ?? (() => new Date().toISOString());
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
// Whether a real backend has been installed via initLogger. Lets diagnostics
|
|
64
|
+
// that must not be swallowed (config misconfiguration warnings) fall back to
|
|
65
|
+
// console when a host-agnostic consumer uses core without calling initLogger.
|
|
66
|
+
export function isLoggerInitialized(): boolean {
|
|
67
|
+
return _backend !== NOOP_LOGGER;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Restore the pristine no-op backend (as at module load, before initLogger).
|
|
71
|
+
// Primarily a test seam for exercising the standalone/no-host path.
|
|
72
|
+
export function resetLogger(): void {
|
|
73
|
+
_backend = NOOP_LOGGER;
|
|
74
|
+
_debug = false;
|
|
75
|
+
_timestamps = true;
|
|
76
|
+
_clock = () => new Date().toISOString();
|
|
77
|
+
}
|
|
78
|
+
|
|
63
79
|
// Format one log line: "<iso> remnic: <msg>" when timestamps are enabled,
|
|
64
80
|
// otherwise the legacy "remnic: <msg>". Timestamp is per-call.
|
|
65
81
|
function fmt(msg: string, label = "remnic"): string {
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import path from "node:path";
|
|
16
|
+
import { createReadStream, type ReadStream } from "node:fs";
|
|
16
17
|
import { appendFile, lstat, mkdir, readdir, readFile } from "node:fs/promises";
|
|
18
|
+
import { createInterface } from "node:readline";
|
|
17
19
|
|
|
18
20
|
// ── Types ─────────────────────────────────────────────────────────────────────
|
|
19
21
|
|
|
@@ -108,50 +110,100 @@ export async function appendDreamsLedgerEntry(
|
|
|
108
110
|
// ── Reader ────────────────────────────────────────────────────────────────────
|
|
109
111
|
|
|
110
112
|
/**
|
|
111
|
-
* Parse
|
|
112
|
-
*
|
|
113
|
+
* Parse and validate one ledger line into a `DreamsLedgerEntry`, or `null` when
|
|
114
|
+
* blank/malformed/incomplete. Shared by the streaming reader and the windowed
|
|
115
|
+
* status aggregator so both apply the identical fail-open guard.
|
|
113
116
|
*/
|
|
114
|
-
|
|
117
|
+
function parseDreamsLedgerLine(line: string): DreamsLedgerEntry | null {
|
|
118
|
+
const trimmed = line.trim();
|
|
119
|
+
if (!trimmed) return null;
|
|
120
|
+
let parsed: Record<string, unknown>;
|
|
121
|
+
try {
|
|
122
|
+
const raw = JSON.parse(trimmed);
|
|
123
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
124
|
+
parsed = raw as Record<string, unknown>;
|
|
125
|
+
} catch {
|
|
126
|
+
return null; // Malformed JSON — skip (fail-open).
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Required, strongly-typed fields. A row missing or mistyping any of these is
|
|
130
|
+
// not a usable telemetry entry.
|
|
131
|
+
const phase = parsed.phase;
|
|
132
|
+
if (phase !== "lightSleep" && phase !== "rem" && phase !== "deepSleep") return null;
|
|
133
|
+
if (
|
|
134
|
+
typeof parsed.startedAt !== "string" ||
|
|
135
|
+
typeof parsed.completedAt !== "string" ||
|
|
136
|
+
typeof parsed.durationMs !== "number" ||
|
|
137
|
+
typeof parsed.itemsProcessed !== "number"
|
|
138
|
+
) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Optional fields: absence is tolerated (older entries predate them, no
|
|
143
|
+
// backfill), but a PRESENT value with the wrong type/value marks the row
|
|
144
|
+
// malformed and skips it — never silently coerced to a default (issue #1910).
|
|
145
|
+
if ("schemaVersion" in parsed && parsed.schemaVersion !== 1) return null;
|
|
146
|
+
if ("dryRun" in parsed && typeof parsed.dryRun !== "boolean") return null;
|
|
147
|
+
if ("trigger" in parsed && parsed.trigger !== "manual" && parsed.trigger !== "scheduled") {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
schemaVersion: 1,
|
|
153
|
+
startedAt: parsed.startedAt,
|
|
154
|
+
completedAt: parsed.completedAt,
|
|
155
|
+
durationMs: parsed.durationMs,
|
|
156
|
+
phase,
|
|
157
|
+
itemsProcessed: parsed.itemsProcessed,
|
|
158
|
+
dryRun: parsed.dryRun === true,
|
|
159
|
+
trigger: parsed.trigger === "manual" ? "manual" : "scheduled",
|
|
160
|
+
notes: typeof parsed.notes === "string" ? parsed.notes : undefined,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Stream the dreams ledger line-by-line. The ledger is plaintext `appendFile`
|
|
166
|
+
* (never encrypted), so a raw line stream is safe at any size — heap stays
|
|
167
|
+
* O(1) in the file, unlike the previous whole-file `readFile` + `split`.
|
|
168
|
+
* Yields nothing when the ledger does not exist yet.
|
|
169
|
+
*/
|
|
170
|
+
export async function* streamDreamsLedgerLines(memoryDir: string): AsyncGenerator<string> {
|
|
115
171
|
const ledgerPath = dreamsLedgerPath(memoryDir);
|
|
116
|
-
let
|
|
172
|
+
let input: ReadStream;
|
|
173
|
+
try {
|
|
174
|
+
input = createReadStream(ledgerPath, { encoding: "utf8" });
|
|
175
|
+
} catch (err) {
|
|
176
|
+
if ((err as NodeJS.ErrnoException).code === "ENOENT") return;
|
|
177
|
+
throw err;
|
|
178
|
+
}
|
|
179
|
+
const rl = createInterface({ input, crlfDelay: Infinity });
|
|
117
180
|
try {
|
|
118
|
-
|
|
181
|
+
for await (const line of rl) yield line;
|
|
119
182
|
} catch (err) {
|
|
120
|
-
|
|
121
|
-
if (code === "ENOENT") return [];
|
|
183
|
+
if ((err as NodeJS.ErrnoException).code === "ENOENT") return;
|
|
122
184
|
throw err;
|
|
185
|
+
} finally {
|
|
186
|
+
// Close the readline interface AND destroy the underlying stream. When a
|
|
187
|
+
// consumer stops early (e.g. `getDreamsStatus` breaks out), the generator's
|
|
188
|
+
// `.return()` runs this finally; `rl.close()` alone leaves the file
|
|
189
|
+
// descriptor open, so destroy the stream to release it (issue #1910).
|
|
190
|
+
rl.close();
|
|
191
|
+
input.destroy();
|
|
123
192
|
}
|
|
193
|
+
}
|
|
124
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Parse all valid `DreamsLedgerEntry` rows from the ledger file. Thin wrapper
|
|
197
|
+
* over the line stream so any caller that genuinely needs every row still
|
|
198
|
+
* works; `getDreamsStatus` streams directly and filters in-window instead.
|
|
199
|
+
* Malformed lines are silently skipped (resilience over strictness for
|
|
200
|
+
* telemetry).
|
|
201
|
+
*/
|
|
202
|
+
export async function readDreamsLedgerEntries(memoryDir: string): Promise<DreamsLedgerEntry[]> {
|
|
125
203
|
const entries: DreamsLedgerEntry[] = [];
|
|
126
|
-
for (const line of
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
129
|
-
try {
|
|
130
|
-
const parsed = JSON.parse(trimmed) as Partial<DreamsLedgerEntry>;
|
|
131
|
-
if (typeof parsed !== "object" || parsed === null) continue;
|
|
132
|
-
if (
|
|
133
|
-
typeof parsed.phase === "string" &&
|
|
134
|
-
(parsed.phase === "lightSleep" || parsed.phase === "rem" || parsed.phase === "deepSleep") &&
|
|
135
|
-
typeof parsed.startedAt === "string" &&
|
|
136
|
-
typeof parsed.completedAt === "string" &&
|
|
137
|
-
typeof parsed.durationMs === "number" &&
|
|
138
|
-
typeof parsed.itemsProcessed === "number"
|
|
139
|
-
) {
|
|
140
|
-
entries.push({
|
|
141
|
-
schemaVersion: 1,
|
|
142
|
-
startedAt: parsed.startedAt,
|
|
143
|
-
completedAt: parsed.completedAt,
|
|
144
|
-
durationMs: parsed.durationMs,
|
|
145
|
-
phase: parsed.phase,
|
|
146
|
-
itemsProcessed: parsed.itemsProcessed,
|
|
147
|
-
dryRun: parsed.dryRun === true,
|
|
148
|
-
trigger: parsed.trigger === "manual" ? "manual" : "scheduled",
|
|
149
|
-
notes: typeof parsed.notes === "string" ? parsed.notes : undefined,
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
} catch {
|
|
153
|
-
// Malformed line — skip.
|
|
154
|
-
}
|
|
204
|
+
for await (const line of streamDreamsLedgerLines(memoryDir)) {
|
|
205
|
+
const entry = parseDreamsLedgerLine(line);
|
|
206
|
+
if (entry) entries.push(entry);
|
|
155
207
|
}
|
|
156
208
|
return entries;
|
|
157
209
|
}
|
|
@@ -199,13 +251,8 @@ export async function getDreamsStatus(
|
|
|
199
251
|
throw new RangeError("windowHours produces an invalid status window");
|
|
200
252
|
}
|
|
201
253
|
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
// Filter to entries within the window based on completedAt.
|
|
205
|
-
const windowEntries = entries.filter((e) => {
|
|
206
|
-
const ts = Date.parse(e.completedAt);
|
|
207
|
-
return Number.isFinite(ts) && ts >= windowStart.getTime() && ts < windowEnd.getTime();
|
|
208
|
-
});
|
|
254
|
+
const windowStartMs = windowStart.getTime();
|
|
255
|
+
const windowEndMs = windowEnd.getTime();
|
|
209
256
|
|
|
210
257
|
const statusMap = new Map<DreamsPhase, DreamsPhaseStatus>();
|
|
211
258
|
for (const phase of ALL_PHASES) {
|
|
@@ -219,18 +266,22 @@ export async function getDreamsStatus(
|
|
|
219
266
|
});
|
|
220
267
|
}
|
|
221
268
|
|
|
222
|
-
|
|
269
|
+
// Stream the ledger and aggregate every in-window row inline, so heap use is
|
|
270
|
+
// O(number of phases) regardless of window or file size (issue #1910) — no
|
|
271
|
+
// per-row array and no row cap, so a large in-window window is still counted
|
|
272
|
+
// in full rather than truncated.
|
|
273
|
+
for await (const line of streamDreamsLedgerLines(memoryDir)) {
|
|
274
|
+
const entry = parseDreamsLedgerLine(line);
|
|
275
|
+
if (!entry) continue;
|
|
276
|
+
const ts = Date.parse(entry.completedAt);
|
|
277
|
+
if (!Number.isFinite(ts) || ts < windowStartMs || ts >= windowEndMs) continue;
|
|
223
278
|
const status = statusMap.get(entry.phase);
|
|
224
279
|
if (!status) continue;
|
|
225
280
|
status.runCount += 1;
|
|
226
281
|
status.totalDurationMs += entry.durationMs;
|
|
227
282
|
status.totalItemsProcessed += entry.itemsProcessed;
|
|
228
|
-
|
|
229
283
|
// Track the most recent run (by completedAt).
|
|
230
|
-
if (
|
|
231
|
-
status.lastRunAt === null ||
|
|
232
|
-
Date.parse(entry.completedAt) > Date.parse(status.lastRunAt)
|
|
233
|
-
) {
|
|
284
|
+
if (status.lastRunAt === null || ts > Date.parse(status.lastRunAt)) {
|
|
234
285
|
status.lastRunAt = entry.completedAt;
|
|
235
286
|
status.lastDurationMs = entry.durationMs;
|
|
236
287
|
}
|