@remnic/core 9.7.15 → 9.9.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 +85 -71
- package/dist/access-audit.js +2 -2
- package/dist/access-boundary.d.ts +35 -17
- package/dist/access-boundary.js +86 -74
- package/dist/access-citation.d.ts +28 -0
- package/dist/access-citation.js +9 -0
- package/dist/access-cli.js +194 -178
- 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 +100 -87
- package/dist/access-identity-continuity-surface.d.ts +13 -8
- package/dist/access-identity-continuity-surface.js +85 -71
- package/dist/access-lcm-surface.d.ts +16 -9
- package/dist/access-lcm-surface.js +85 -71
- package/dist/access-mcp.d.ts +23 -16
- package/dist/access-mcp.js +96 -84
- 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 +85 -71
- package/dist/access-operations-batch.js +92 -80
- package/dist/access-operations.d.ts +29 -22
- package/dist/access-operations.js +94 -82
- 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 +85 -71
- package/dist/access-schema.d.ts +98 -98
- package/dist/access-schema.js +8 -6
- package/dist/{access-service-DpcYZ9Nl.d.ts → access-service-DbZ1G3zV.d.ts} +29 -36
- package/dist/access-service.d.ts +13 -6
- package/dist/access-service.js +89 -72
- 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 +34 -24
- 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/{catalog-C9444P10.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 +43 -34
- 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-L2B3EE7B.js → chunk-2QMKMVHH.js} +2 -2
- package/dist/{chunk-VJVNLNDQ.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-HDTQVNWD.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-LRNMRXJO.js → chunk-3Y224NYC.js} +3 -3
- package/dist/{chunk-3IY64MV6.js → chunk-44XZ75OQ.js} +44 -10
- package/dist/chunk-44XZ75OQ.js.map +1 -0
- package/dist/{chunk-VFSP73LP.js → chunk-45GF7Y3V.js} +2 -2
- package/dist/{chunk-K7LOWSLU.js → chunk-4BJQODZF.js} +2479 -1520
- package/dist/chunk-4BJQODZF.js.map +1 -0
- package/dist/{chunk-JREB6UFH.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-2AZXIZEN.js → chunk-5Q7EVV4X.js} +6 -6
- package/dist/{chunk-LC7OODWZ.js → chunk-5SB7SC2G.js} +80 -49
- package/dist/chunk-5SB7SC2G.js.map +1 -0
- 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-FDCTQWLW.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-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-ZHIVCODT.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-A5UXZRRM.js → chunk-AJ7QCSIS.js} +2 -2
- 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-QKQYXZVS.js → chunk-BI2OJF6J.js} +1819 -1481
- package/dist/chunk-BI2OJF6J.js.map +1 -0
- package/dist/{chunk-GWTFLF2P.js → chunk-BJMBJZ2Y.js} +59 -59
- package/dist/chunk-BJMBJZ2Y.js.map +1 -0
- package/dist/{chunk-74F5STS4.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-T7Y5KPLN.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-EHCONI6E.js → chunk-CQMEM5CC.js} +2 -2
- package/dist/{chunk-PBNZVPFS.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-INELTPRG.js → chunk-EEC7UJPX.js} +103 -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-DZKHSDOM.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-DMSDUGDM.js → chunk-F7GAIWFA.js} +20 -20
- package/dist/{chunk-G6XXLKC5.js → chunk-FFPJINJE.js} +6 -6
- 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-G4CN3ZXL.js → chunk-FUTF72MJ.js} +15 -15
- package/dist/chunk-GCASGYIO.js +71 -0
- package/dist/chunk-GCASGYIO.js.map +1 -0
- package/dist/{chunk-HF77M34J.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-UDQUSU27.js → chunk-HNZKVLAN.js} +2 -2
- package/dist/{chunk-5EZXHU36.js → chunk-HYQJQGD3.js} +2 -2
- package/dist/{chunk-PLQE6MJA.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-TRWPCR6P.js → chunk-JECBQBEX.js} +3 -3
- package/dist/{chunk-E6CBU7XP.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-KDXVOFYY.js → chunk-KAVBJSBQ.js} +4 -4
- package/dist/{chunk-BS4SGLWV.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-2S6QHZGJ.js → chunk-L2DPF4DF.js} +1 -1
- 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-QQGPUKMT.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-Q5WG43OP.js → chunk-MYFQ3ED4.js} +7 -7
- 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-OAZVR2BV.js → chunk-OGCAYLNA.js} +8 -6
- package/dist/{chunk-OAZVR2BV.js.map → chunk-OGCAYLNA.js.map} +1 -1
- package/dist/{chunk-DBRYEIGY.js → chunk-OJP3N7UK.js} +2 -2
- package/dist/{chunk-VDW4VU7B.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-PJSK6OJM.js +201 -0
- package/dist/chunk-PJSK6OJM.js.map +1 -0
- package/dist/{chunk-OVJ2HIPE.js → chunk-PMUD7ERF.js} +158 -125
- package/dist/chunk-PMUD7ERF.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-DYP3YYJJ.js → chunk-QJAQNXWI.js} +39 -5
- package/dist/chunk-QJAQNXWI.js.map +1 -0
- package/dist/{chunk-3D6AFGQR.js → chunk-QVT3E4CE.js} +7 -7
- package/dist/{chunk-FIJUY7GG.js → chunk-R26ZMXR2.js} +23 -23
- package/dist/{chunk-FIJUY7GG.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-FNZQGN76.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-SK7AMF2J.js +168 -0
- package/dist/chunk-SK7AMF2J.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-DPAENM7O.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-AJLLIIML.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-RO4LQGT3.js → chunk-WON4APQY.js} +4 -4
- package/dist/{chunk-PQVK2S3J.js → chunk-WZFAPHIK.js} +6 -6
- package/dist/{chunk-KQPJLK3X.js → chunk-XL24QQ63.js} +2 -2
- package/dist/{chunk-LZOV7MX7.js → chunk-XQDRKZ7V.js} +6476 -5747
- package/dist/chunk-XQDRKZ7V.js.map +1 -0
- package/dist/{chunk-RVZRYUQH.js → chunk-YROFNEG5.js} +7 -7
- package/dist/{chunk-RAR2BSEM.js → chunk-YV32N67O.js} +1 -1
- package/dist/chunk-YV32N67O.js.map +1 -0
- package/dist/{chunk-PBSAPHHA.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/{chunk-DCFV7A7H.js → chunk-ZVAYK7GU.js} +101 -91
- package/dist/chunk-ZVAYK7GU.js.map +1 -0
- package/dist/{cli-Cd5fMmhq.d.ts → cli-5tNLVTvJ.d.ts} +28 -12
- package/dist/cli.d.ts +16 -9
- package/dist/cli.js +142 -127
- package/dist/compounding/engine.d.ts +5 -2
- package/dist/compounding/engine.js +36 -26
- 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 +36 -26
- 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 +41 -32
- package/dist/consolidation-provenance-check.d.ts +5 -2
- package/dist/consolidation-undo.d.ts +5 -2
- 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 +35 -26
- 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-IOGBBAGC.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 +3 -1
- 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 +473 -464
- package/dist/index.js +287 -239
- 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 +35 -25
- 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 +37 -25
- package/dist/maintenance/rebuild-memory-projection.js +38 -28
- 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 +3 -1
- 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 +51 -42
- 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 +24 -20
- package/dist/namespaces/storage.d.ts +24 -3
- package/dist/namespaces/storage.js +35 -27
- 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 +69 -54
- 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 +44 -31
- package/dist/{orchestrator-Bp_jeBHK.d.ts → orchestrator-CQJ8U7En.d.ts} +85 -79
- package/dist/orchestrator.d.ts +13 -8
- package/dist/orchestrator.js +194 -177
- package/dist/patterns-cli.d.ts +3 -1
- package/dist/{pipeline-BAj5bx7g.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-_MDSlj1m.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 +7 -3
- 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 +98 -98
- 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 +18 -16
- package/dist/search/index.d.ts +3 -1
- package/dist/search/index.js +22 -20
- 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 +16 -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-C2m5eHHE.d.ts → semantic-consolidation-DILZEQq3.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +4 -2
- package/dist/semantic-consolidation.js +38 -29
- package/dist/semantic-rule-promotion.js +34 -24
- package/dist/semantic-rule-verifier.d.ts +3 -1
- package/dist/semantic-rule-verifier.js +35 -25
- 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 +11 -9
- package/dist/shared-context/manager.js +3 -3
- package/dist/signal.d.ts +3 -1
- package/dist/{storage-hr_Y2z5R.d.ts → storage-NIyKYD8g.d.ts} +489 -110
- package/dist/storage-guards.js +2 -2
- package/dist/storage.d.ts +6 -3
- package/dist/storage.js +38 -26
- 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 +3 -3
- package/dist/transfer/types.d.ts +90 -90
- 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-Cg8q7W7_.d.ts → types-D_fG2ix8.d.ts} +39 -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 +36 -26
- 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 +94 -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 +172 -0
- package/src/access-observe-write-surface.ts +137 -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 +186 -179
- 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 +113 -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/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-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 +43 -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 +574 -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 +168 -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 +160 -149
- 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.ts +47 -47
- 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 +13 -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 +882 -890
- 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 +51 -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 +245 -0
- package/src/write-quarantine.ts +290 -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-3IY64MV6.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-BS4SGLWV.js.map +0 -1
- package/dist/chunk-DCFV7A7H.js.map +0 -1
- package/dist/chunk-DYP3YYJJ.js.map +0 -1
- package/dist/chunk-E5BK6CGV.js +0 -335
- package/dist/chunk-E5BK6CGV.js.map +0 -1
- package/dist/chunk-FTYDWKO6.js.map +0 -1
- package/dist/chunk-GWTFLF2P.js.map +0 -1
- package/dist/chunk-IKQTFQMI.js.map +0 -1
- package/dist/chunk-INELTPRG.js.map +0 -1
- package/dist/chunk-J2HSAU72.js.map +0 -1
- package/dist/chunk-JREB6UFH.js.map +0 -1
- package/dist/chunk-K7LOWSLU.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-LZOV7MX7.js.map +0 -1
- package/dist/chunk-NWTGD4AN.js.map +0 -1
- package/dist/chunk-ODPLEWB6.js.map +0 -1
- package/dist/chunk-OVJ2HIPE.js.map +0 -1
- package/dist/chunk-PBSAPHHA.js.map +0 -1
- package/dist/chunk-PHK3HARR.js +0 -32
- package/dist/chunk-PHK3HARR.js.map +0 -1
- package/dist/chunk-PLQE6MJA.js.map +0 -1
- package/dist/chunk-QKQYXZVS.js.map +0 -1
- package/dist/chunk-QQGPUKMT.js.map +0 -1
- package/dist/chunk-RANHFI3P.js +0 -8
- package/dist/chunk-RANHFI3P.js.map +0 -1
- package/dist/chunk-RAR2BSEM.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-T7Y5KPLN.js.map +0 -1
- package/dist/chunk-TXLGHDHS.js.map +0 -1
- package/dist/chunk-VDW4VU7B.js.map +0 -1
- package/dist/chunk-VSMRDBFT.js +0 -17
- package/dist/chunk-VSMRDBFT.js.map +0 -1
- package/dist/chunk-X64YLC24.js.map +0 -1
- package/dist/chunk-XDSXEKYK.js +0 -118
- package/dist/chunk-XDSXEKYK.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-IOGBBAGC.js.map → access-recall-response.js.map} +0 -0
- /package/dist/{resolution-VH4NGENZ.js.map → bounded-jsonl-state.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-VJVNLNDQ.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-HDTQVNWD.js.map → chunk-3QAH2S33.js.map} +0 -0
- /package/dist/{chunk-LRNMRXJO.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-2AZXIZEN.js.map → chunk-5Q7EVV4X.js.map} +0 -0
- /package/dist/{chunk-PUBTHW5O.js.map → chunk-6DRPPQEJ.js.map} +0 -0
- /package/dist/{chunk-FDCTQWLW.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-ZHIVCODT.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-A5UXZRRM.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-74F5STS4.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-EHCONI6E.js.map → chunk-CQMEM5CC.js.map} +0 -0
- /package/dist/{chunk-PBNZVPFS.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-DZKHSDOM.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-DMSDUGDM.js.map → chunk-F7GAIWFA.js.map} +0 -0
- /package/dist/{chunk-G6XXLKC5.js.map → chunk-FFPJINJE.js.map} +0 -0
- /package/dist/{chunk-G4CN3ZXL.js.map → chunk-FUTF72MJ.js.map} +0 -0
- /package/dist/{chunk-HF77M34J.js.map → chunk-GFPZS3F5.js.map} +0 -0
- /package/dist/{chunk-G6NKALRN.js.map → chunk-H4WG3UQZ.js.map} +0 -0
- /package/dist/{chunk-UDQUSU27.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-E6CBU7XP.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-KDXVOFYY.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-2S6QHZGJ.js.map → chunk-L2DPF4DF.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-Q5WG43OP.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-FNZQGN76.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-DPAENM7O.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-AJLLIIML.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-RO4LQGT3.js.map → chunk-WON4APQY.js.map} +0 -0
- /package/dist/{chunk-PQVK2S3J.js.map → chunk-WZFAPHIK.js.map} +0 -0
- /package/dist/{chunk-KQPJLK3X.js.map → chunk-XL24QQ63.js.map} +0 -0
- /package/dist/{chunk-RVZRYUQH.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
|
@@ -7,6 +7,7 @@ import type { BufferState, BufferTurn } from "./types.js";
|
|
|
7
7
|
|
|
8
8
|
class FakeStorage {
|
|
9
9
|
public saved: BufferState | null = null;
|
|
10
|
+
public saveCount = 0;
|
|
10
11
|
|
|
11
12
|
constructor(private readonly initial: BufferState) {}
|
|
12
13
|
|
|
@@ -15,6 +16,7 @@ class FakeStorage {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
async saveBuffer(state: BufferState): Promise<void> {
|
|
19
|
+
this.saveCount += 1;
|
|
18
20
|
this.saved = structuredClone(state);
|
|
19
21
|
}
|
|
20
22
|
}
|
|
@@ -97,7 +99,7 @@ test("SmartBuffer keeps dangerous keys isolated from safe-prefix lookalikes", as
|
|
|
97
99
|
|
|
98
100
|
test("SmartBuffer serializes concurrent addTurn mutations", async () => {
|
|
99
101
|
const storage = new DelayedBufferStorage();
|
|
100
|
-
const buffer = new SmartBuffer(parseConfig({}), storage as
|
|
102
|
+
const buffer = new SmartBuffer(parseConfig({ bufferSaveDebounceMs: 0 }), storage as unknown as ConstructorParameters<typeof SmartBuffer>[1]);
|
|
101
103
|
|
|
102
104
|
await Promise.all([
|
|
103
105
|
buffer.addTurn("thread-a", makeTurn("thread-a", "alpha memory")),
|
|
@@ -270,7 +272,7 @@ test("SmartBuffer read-only accessors do not persist phantom entries for unknown
|
|
|
270
272
|
lastExtractionAt: null,
|
|
271
273
|
extractionCount: 0,
|
|
272
274
|
});
|
|
273
|
-
const buffer = new SmartBuffer(parseConfig({}), storage as
|
|
275
|
+
const buffer = new SmartBuffer(parseConfig({ bufferSaveDebounceMs: 0 }), storage as unknown as ConstructorParameters<typeof SmartBuffer>[1]);
|
|
274
276
|
|
|
275
277
|
assert.deepEqual(buffer.getTurns("missing-thread"), []);
|
|
276
278
|
assert.equal(buffer.getExtractionCount("missing-thread"), 0);
|
|
@@ -373,7 +375,7 @@ test("SmartBuffer prunes stale logical session buffers to a bounded entry set",
|
|
|
373
375
|
...entries,
|
|
374
376
|
},
|
|
375
377
|
});
|
|
376
|
-
const buffer = new SmartBuffer(parseConfig({}), storage as
|
|
378
|
+
const buffer = new SmartBuffer(parseConfig({ bufferSaveDebounceMs: 0 }), storage as unknown as ConstructorParameters<typeof SmartBuffer>[1]);
|
|
377
379
|
|
|
378
380
|
await buffer.addTurn("active-thread", makeTurn("active-thread", "pending memory"));
|
|
379
381
|
|
|
@@ -522,7 +524,7 @@ test("SmartBuffer prefers pruning empty entries and bounds pending-turn buffers
|
|
|
522
524
|
...entries,
|
|
523
525
|
},
|
|
524
526
|
});
|
|
525
|
-
const buffer = new SmartBuffer(parseConfig({}), storage as unknown as ConstructorParameters<typeof SmartBuffer>[1]);
|
|
527
|
+
const buffer = new SmartBuffer(parseConfig({ bufferSaveDebounceMs: 0 }), storage as unknown as ConstructorParameters<typeof SmartBuffer>[1]);
|
|
526
528
|
|
|
527
529
|
await buffer.addTurn("active-thread", makeTurn("active-thread", "pending memory"));
|
|
528
530
|
|
|
@@ -549,7 +551,7 @@ test("pruneEntries evicts oldest NON-empty session entries past the cap (#1908 r
|
|
|
549
551
|
};
|
|
550
552
|
}
|
|
551
553
|
const storage = new FakeStorage({ turns: [], lastExtractionAt: null, extractionCount: 0, entries });
|
|
552
|
-
const buffer = new SmartBuffer(parseConfig({}), storage as unknown as ConstructorParameters<typeof SmartBuffer>[1]);
|
|
554
|
+
const buffer = new SmartBuffer(parseConfig({ bufferSaveDebounceMs: 0 }), storage as unknown as ConstructorParameters<typeof SmartBuffer>[1]);
|
|
553
555
|
await buffer.load();
|
|
554
556
|
await buffer.addTurn("session-newest", makeTurn("session-newest", "new turn"));
|
|
555
557
|
|
|
@@ -559,3 +561,418 @@ test("pruneEntries evicts oldest NON-empty session entries past the cap (#1908 r
|
|
|
559
561
|
assert.equal(buffer.getTurns("session-000").length, 0, "oldest non-empty entry was evicted");
|
|
560
562
|
assert.ok(buffer.getTurns("session-209").length > 0, "newest pre-existing entry survives");
|
|
561
563
|
});
|
|
564
|
+
|
|
565
|
+
// ---------------------------------------------------------------------------
|
|
566
|
+
// Issue #1909 (Part D) — debounced buffer save
|
|
567
|
+
// ---------------------------------------------------------------------------
|
|
568
|
+
|
|
569
|
+
function emptyBufferState(): BufferState {
|
|
570
|
+
return { turns: [], lastExtractionAt: null, extractionCount: 0 };
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
interface DebouncedBufferInternals {
|
|
574
|
+
saveTimer: NodeJS.Timeout | null;
|
|
575
|
+
pendingSave: boolean;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
test("debounce on: N keep_buffering turns coalesce into one save on flush", async () => {
|
|
579
|
+
const storage = new FakeStorage(emptyBufferState());
|
|
580
|
+
// Large window + high turn cap so every turn keeps buffering (no trigger).
|
|
581
|
+
const buffer = new SmartBuffer(
|
|
582
|
+
parseConfig({ bufferSaveDebounceMs: 10_000, triggerMode: "smart", bufferMaxTurns: 100 }),
|
|
583
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
584
|
+
);
|
|
585
|
+
|
|
586
|
+
for (let i = 0; i < 5; i += 1) {
|
|
587
|
+
const decision = await buffer.addTurn("thread-a", makeTurn("thread-a", `turn ${i}`));
|
|
588
|
+
assert.equal(decision, "keep_buffering");
|
|
589
|
+
}
|
|
590
|
+
assert.equal(storage.saveCount, 0, "steady-state buffering does zero full serializations");
|
|
591
|
+
|
|
592
|
+
await buffer.flushPendingSave();
|
|
593
|
+
assert.equal(storage.saveCount, 1, "the trailing-edge flush writes exactly once");
|
|
594
|
+
assert.equal(storage.saved?.entries?.["thread-a"]?.turns.length, 5, "flush persists all buffered turns");
|
|
595
|
+
|
|
596
|
+
// Idempotent: a second flush with nothing pending does not write again.
|
|
597
|
+
await buffer.flushPendingSave();
|
|
598
|
+
assert.equal(storage.saveCount, 1, "flushPendingSave is idempotent");
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
test("debounce on: an extraction-triggering turn forces an immediate save", async () => {
|
|
602
|
+
const storage = new FakeStorage(emptyBufferState());
|
|
603
|
+
const buffer = new SmartBuffer(
|
|
604
|
+
parseConfig({ bufferSaveDebounceMs: 10_000, triggerMode: "smart", bufferMaxTurns: 1 }),
|
|
605
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
606
|
+
);
|
|
607
|
+
|
|
608
|
+
const decision = await buffer.addTurn("thread-a", makeTurn("thread-a", "trigger"));
|
|
609
|
+
assert.notEqual(decision, "keep_buffering", "the turn triggers extraction");
|
|
610
|
+
assert.equal(storage.saveCount, 1, "the triggering turn is durable immediately, not on the debounce edge");
|
|
611
|
+
assert.equal(storage.saved?.entries?.["thread-a"]?.turns.length, 1);
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
test("debounce on: clearAfterExtraction cancels the pending timer and persists post-clear state", async () => {
|
|
615
|
+
const storage = new FakeStorage(emptyBufferState());
|
|
616
|
+
const buffer = new SmartBuffer(
|
|
617
|
+
parseConfig({ bufferSaveDebounceMs: 10_000, triggerMode: "smart", bufferMaxTurns: 100 }),
|
|
618
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
619
|
+
);
|
|
620
|
+
|
|
621
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "buffered turn"));
|
|
622
|
+
assert.equal(storage.saveCount, 0, "the buffered turn's save is still pending on the timer");
|
|
623
|
+
|
|
624
|
+
await buffer.clearAfterExtraction("thread-a");
|
|
625
|
+
assert.equal(storage.saveCount, 1, "clearAfterExtraction persists exactly once (post-clear state)");
|
|
626
|
+
assert.equal(storage.saved?.entries?.["thread-a"]?.turns.length, 0, "the persisted state is cleared");
|
|
627
|
+
|
|
628
|
+
// The pending debounce timer was cancelled — it must not fire a stale write.
|
|
629
|
+
const internals = buffer as unknown as DebouncedBufferInternals;
|
|
630
|
+
assert.equal(internals.saveTimer, null, "no armed timer remains after clear");
|
|
631
|
+
assert.equal(internals.pendingSave, false, "no pending save remains after clear");
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
test("debounce off (bufferSaveDebounceMs: 0) reproduces save-every-turn", async () => {
|
|
635
|
+
const storage = new FakeStorage(emptyBufferState());
|
|
636
|
+
const buffer = new SmartBuffer(
|
|
637
|
+
parseConfig({ bufferSaveDebounceMs: 0, triggerMode: "smart", bufferMaxTurns: 100 }),
|
|
638
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
639
|
+
);
|
|
640
|
+
|
|
641
|
+
for (let i = 0; i < 4; i += 1) {
|
|
642
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", `turn ${i}`));
|
|
643
|
+
}
|
|
644
|
+
assert.equal(storage.saveCount, 4, "with debounce disabled every turn saves immediately");
|
|
645
|
+
assert.equal(storage.saved?.entries?.["thread-a"]?.turns.length, 4);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
test("parseConfig validates bufferSaveDebounceMs (accepts valid, defaults undefined)", () => {
|
|
649
|
+
assert.equal(parseConfig({}).bufferSaveDebounceMs, 3_000, "undefined → default 3000ms");
|
|
650
|
+
assert.equal(parseConfig({ bufferSaveDebounceMs: 0 }).bufferSaveDebounceMs, 0, "0 = save every turn");
|
|
651
|
+
assert.equal(parseConfig({ bufferSaveDebounceMs: 5_000 }).bufferSaveDebounceMs, 5_000);
|
|
652
|
+
assert.equal(
|
|
653
|
+
parseConfig({ bufferSaveDebounceMs: 2_147_483_647 }).bufferSaveDebounceMs,
|
|
654
|
+
2_147_483_647,
|
|
655
|
+
"max (32-bit setTimeout limit) accepted",
|
|
656
|
+
);
|
|
657
|
+
// CLI numeric strings coerce, then validate.
|
|
658
|
+
assert.equal(parseConfig({ bufferSaveDebounceMs: "5000" }).bufferSaveDebounceMs, 5_000, "numeric string coerces");
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
test("debounce on: each turn re-arms the trailing edge (save fires one window after the LAST turn)", async (t) => {
|
|
662
|
+
t.mock.timers.enable({ apis: ["setTimeout", "Date"], now: 0 });
|
|
663
|
+
const storage = new FakeStorage(emptyBufferState());
|
|
664
|
+
const buffer = new SmartBuffer(
|
|
665
|
+
parseConfig({ bufferSaveDebounceMs: 100, triggerMode: "smart", bufferMaxTurns: 10_000 }),
|
|
666
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
667
|
+
);
|
|
668
|
+
const settle = () => new Promise<void>((resolve) => setImmediate(resolve));
|
|
669
|
+
|
|
670
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "turn 0")); // schedules save at t=100
|
|
671
|
+
t.mock.timers.tick(90); // t=90, before the first window closes
|
|
672
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "turn 1")); // re-arms to t=190
|
|
673
|
+
t.mock.timers.tick(90); // t=180 — the ORIGINAL 100ms deadline is past
|
|
674
|
+
await settle();
|
|
675
|
+
assert.equal(storage.saveCount, 0, "re-arm pushed the deadline; no save at the original window");
|
|
676
|
+
|
|
677
|
+
t.mock.timers.tick(20); // t=200 — 110ms after the last turn (past the re-armed 190)
|
|
678
|
+
await settle();
|
|
679
|
+
assert.equal(storage.saveCount, 1, "the save fires one window after the LAST turn (true trailing edge)");
|
|
680
|
+
assert.equal(storage.saved?.entries?.["thread-a"]?.turns.length, 2);
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
test("debounce on: sustained activity forces an inline save at the 5x staleness cap", async (t) => {
|
|
684
|
+
t.mock.timers.enable({ apis: ["setTimeout", "Date"], now: 0 });
|
|
685
|
+
const storage = new FakeStorage(emptyBufferState());
|
|
686
|
+
// Window 100ms → cap at 5x = 500ms of continuously-deferred pending state.
|
|
687
|
+
const buffer = new SmartBuffer(
|
|
688
|
+
parseConfig({ bufferSaveDebounceMs: 100, triggerMode: "smart", bufferMaxTurns: 10_000 }),
|
|
689
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
690
|
+
);
|
|
691
|
+
|
|
692
|
+
// Add a turn every 80ms (< window) so the trailing-edge timer never fires —
|
|
693
|
+
// each turn re-arms it. The pending save is deferred continuously.
|
|
694
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "turn 0")); // firstPendingAt = 0
|
|
695
|
+
for (let elapsed = 80; elapsed <= 480; elapsed += 80) {
|
|
696
|
+
t.mock.timers.tick(80);
|
|
697
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", `turn @${elapsed}`));
|
|
698
|
+
assert.equal(storage.saveCount, 0, `still deferred at t=${elapsed} (< 5x window)`);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Next turn crosses t=560 (>= 500ms cap): scheduleSave forces an inline save.
|
|
702
|
+
t.mock.timers.tick(80); // t=560
|
|
703
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "turn @560"));
|
|
704
|
+
assert.equal(storage.saveCount, 1, "the 5x staleness cap forced an inline save mid-activity");
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
class FailOnceBufferStorage {
|
|
708
|
+
public saved: BufferState | null = null;
|
|
709
|
+
public saveCount = 0;
|
|
710
|
+
public failNext = true;
|
|
711
|
+
|
|
712
|
+
async loadBuffer(): Promise<BufferState> {
|
|
713
|
+
return emptyBufferState();
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
async saveBuffer(state: BufferState): Promise<void> {
|
|
717
|
+
if (this.failNext) {
|
|
718
|
+
this.failNext = false;
|
|
719
|
+
throw new Error("simulated buffer write failure");
|
|
720
|
+
}
|
|
721
|
+
this.saveCount += 1;
|
|
722
|
+
this.saved = structuredClone(state);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
test("debounce on: a failed flush keeps the save pending so a retry (or shutdown) persists", async () => {
|
|
727
|
+
// Issue #1909 review round 2 finding 1: flushPendingSave must not clear
|
|
728
|
+
// pendingSave until the write SUCCEEDS — otherwise a failed write diverges
|
|
729
|
+
// memory from disk and a later shutdown flush early-returns, dropping turns.
|
|
730
|
+
const storage = new FailOnceBufferStorage();
|
|
731
|
+
const buffer = new SmartBuffer(
|
|
732
|
+
parseConfig({ bufferSaveDebounceMs: 10_000, triggerMode: "smart", bufferMaxTurns: 10_000 }),
|
|
733
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
734
|
+
);
|
|
735
|
+
|
|
736
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "buffered turn")); // schedules a save
|
|
737
|
+
// First flush: the underlying write throws (swallowed, fail-open).
|
|
738
|
+
await buffer.flushPendingSave();
|
|
739
|
+
const internals = buffer as unknown as DebouncedBufferInternals;
|
|
740
|
+
assert.equal(internals.pendingSave, true, "a failed save leaves the save pending for retry");
|
|
741
|
+
assert.equal(storage.saveCount, 0, "nothing was persisted on the failed attempt");
|
|
742
|
+
|
|
743
|
+
// Retry (mirrors the re-armed timer or graceful-shutdown flush) succeeds.
|
|
744
|
+
await buffer.flushPendingSave();
|
|
745
|
+
assert.equal(storage.saveCount, 1, "the retry performed exactly one successful write");
|
|
746
|
+
assert.equal(
|
|
747
|
+
storage.saved?.entries?.["thread-a"]?.turns.length,
|
|
748
|
+
1,
|
|
749
|
+
"the previously-unpersisted turn is now durable",
|
|
750
|
+
);
|
|
751
|
+
assert.equal(internals.pendingSave, false, "pending is cleared only after the write succeeds");
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
test("parseConfig rejects invalid bufferSaveDebounceMs (round 8: throw, do not clamp/floor)", () => {
|
|
755
|
+
// Review round 8: reject invalid user input explicitly instead of silently
|
|
756
|
+
// flooring fractions / clamping negatives to 0 / clamping oversized to the
|
|
757
|
+
// timer max (AGENTS.md #1/#39).
|
|
758
|
+
const cases: unknown[] = [
|
|
759
|
+
-1, // negative
|
|
760
|
+
0.5, // fraction
|
|
761
|
+
3_000_000_000, // above the 32-bit setTimeout limit
|
|
762
|
+
Number.NaN,
|
|
763
|
+
Number.POSITIVE_INFINITY,
|
|
764
|
+
"abc", // non-numeric string
|
|
765
|
+
-0.0001,
|
|
766
|
+
2_147_483_648, // one past max
|
|
767
|
+
null, // explicit null is invalid (only undefined defaults) — round 9 finding 1
|
|
768
|
+
];
|
|
769
|
+
for (const value of cases) {
|
|
770
|
+
assert.throws(
|
|
771
|
+
() => parseConfig({ bufferSaveDebounceMs: value }),
|
|
772
|
+
/bufferSaveDebounceMs must be an integer in \[0, 2147483647\]/,
|
|
773
|
+
`expected ${JSON.stringify(value)} to be rejected`,
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
// Boundary + coercion: valid inputs pass.
|
|
777
|
+
assert.equal(parseConfig({ bufferSaveDebounceMs: 0 }).bufferSaveDebounceMs, 0);
|
|
778
|
+
assert.equal(parseConfig({ bufferSaveDebounceMs: 2_147_483_647 }).bufferSaveDebounceMs, 2_147_483_647);
|
|
779
|
+
assert.equal(parseConfig({ bufferSaveDebounceMs: "5000" }).bufferSaveDebounceMs, 5_000);
|
|
780
|
+
assert.equal(parseConfig({}).bufferSaveDebounceMs, 3_000, "undefined → default");
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
test("debounce cap: the buffer never arms setTimeout above the 32-bit limit", async () => {
|
|
784
|
+
// Deterministic (no real waiting): capture the delay the buffer passes to
|
|
785
|
+
// setTimeout. An unclamped value > 2^31-1 is overflow-clamped by Node to 1ms;
|
|
786
|
+
// the buffer-side Math.min prevents that even when a directly-constructed
|
|
787
|
+
// config bypassed parseConfig's cap.
|
|
788
|
+
const config = parseConfig({ triggerMode: "smart", bufferMaxTurns: 10_000 });
|
|
789
|
+
config.bufferSaveDebounceMs = 3_000_000_000;
|
|
790
|
+
const storage = new FakeStorage(emptyBufferState());
|
|
791
|
+
const buffer = new SmartBuffer(
|
|
792
|
+
config,
|
|
793
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
794
|
+
);
|
|
795
|
+
|
|
796
|
+
const timerGlobal = globalThis as unknown as { setTimeout: typeof setTimeout };
|
|
797
|
+
const realSetTimeout = timerGlobal.setTimeout;
|
|
798
|
+
const armedDelays: number[] = [];
|
|
799
|
+
const fakeHandle = { unref() {}, ref() {} } as unknown as NodeJS.Timeout;
|
|
800
|
+
timerGlobal.setTimeout = ((_fn: (...a: unknown[]) => void, delay?: number) => {
|
|
801
|
+
if (typeof delay === "number") armedDelays.push(delay);
|
|
802
|
+
// Do not schedule the real callback — we only assert on the delay argument.
|
|
803
|
+
return fakeHandle;
|
|
804
|
+
}) as typeof setTimeout;
|
|
805
|
+
try {
|
|
806
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "x")); // arms the debounced save
|
|
807
|
+
} finally {
|
|
808
|
+
timerGlobal.setTimeout = realSetTimeout;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
assert.ok(armedDelays.length >= 1, "a debounced save timer was armed");
|
|
812
|
+
for (const delay of armedDelays) {
|
|
813
|
+
assert.ok(
|
|
814
|
+
delay <= 2_147_483_647,
|
|
815
|
+
`armed setTimeout delay ${delay} must be clamped to the 32-bit limit`,
|
|
816
|
+
);
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
test("debounce on: a failed clearAfterExtraction save keeps pending so other sessions' turns are not lost", async () => {
|
|
821
|
+
// Issue #1909 review round 13: clearAfterExtraction must NOT clear the global
|
|
822
|
+
// pending-save state/timer before its post-clear save is durable. If any
|
|
823
|
+
// session has a debounced save pending and the post-clear write throws, the
|
|
824
|
+
// pending state must be retained + re-armed so shutdown/the timer retries —
|
|
825
|
+
// otherwise buffered turns from OTHER sessions that only ever existed in the
|
|
826
|
+
// debounced state are lost.
|
|
827
|
+
const storage = new FailOnceBufferStorage();
|
|
828
|
+
const buffer = new SmartBuffer(
|
|
829
|
+
parseConfig({ bufferSaveDebounceMs: 10_000, triggerMode: "smart", bufferMaxTurns: 10_000 }),
|
|
830
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
831
|
+
);
|
|
832
|
+
|
|
833
|
+
// Session A buffers a turn — only a debounced save is pending (nothing on disk).
|
|
834
|
+
await buffer.addTurn("session-a", makeTurn("session-a", "A only lives in the pending save"));
|
|
835
|
+
// Session B buffers a turn too — the pending debounced save now covers A + B.
|
|
836
|
+
await buffer.addTurn("session-b", makeTurn("session-b", "B is about to be extracted"));
|
|
837
|
+
assert.equal(storage.saveCount, 0, "both turns are still only in the debounced pending save");
|
|
838
|
+
|
|
839
|
+
const internals = buffer as unknown as DebouncedBufferInternals;
|
|
840
|
+
|
|
841
|
+
// Extract + clear session B. The post-clear save FAILS (FailOnce). The global
|
|
842
|
+
// pending state must survive so A (and the cleared-B state) can still land.
|
|
843
|
+
await assert.rejects(
|
|
844
|
+
() => buffer.clearAfterExtraction("session-b"),
|
|
845
|
+
/simulated buffer write failure/,
|
|
846
|
+
"the failed post-clear save propagates (matching the inline-write guarantee)",
|
|
847
|
+
);
|
|
848
|
+
assert.equal(storage.saveCount, 0, "nothing was persisted on the failed clear");
|
|
849
|
+
assert.equal(
|
|
850
|
+
internals.pendingSave,
|
|
851
|
+
true,
|
|
852
|
+
"a failed clear keeps the save pending (would be false + lost without the round 13 fix)",
|
|
853
|
+
);
|
|
854
|
+
assert.notEqual(internals.saveTimer, null, "a background retry timer is re-armed after the failure");
|
|
855
|
+
|
|
856
|
+
// Retry (mirrors the re-armed timer or graceful shutdown) succeeds.
|
|
857
|
+
await buffer.flushPendingSave();
|
|
858
|
+
assert.equal(storage.saveCount, 1, "the retry performed exactly one successful write");
|
|
859
|
+
assert.equal(internals.pendingSave, false, "pending is cleared only after the durable write");
|
|
860
|
+
assert.equal(
|
|
861
|
+
storage.saved?.entries?.["session-a"]?.turns.length,
|
|
862
|
+
1,
|
|
863
|
+
"session A's turn is retained through the failed clear and later persisted",
|
|
864
|
+
);
|
|
865
|
+
assert.equal(
|
|
866
|
+
storage.saved?.entries?.["session-b"]?.turns.length ?? 0,
|
|
867
|
+
0,
|
|
868
|
+
"session B's turns were cleared by the extraction",
|
|
869
|
+
);
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Storage that can hold ONE saveBuffer call open on a gate so a test can
|
|
874
|
+
* interleave other buffer mutations while a flush's write is in flight. The
|
|
875
|
+
* persisted snapshot is captured at call time (matching FakeStorage), so it
|
|
876
|
+
* reflects exactly the state the flush intended to write.
|
|
877
|
+
*/
|
|
878
|
+
class GatedSaveStorage {
|
|
879
|
+
public saved: BufferState | null = null;
|
|
880
|
+
public saveCount = 0;
|
|
881
|
+
private blockNext = false;
|
|
882
|
+
private release: (() => void) | null = null;
|
|
883
|
+
private signalStarted: (() => void) | null = null;
|
|
884
|
+
private startedPromise: Promise<void> | null = null;
|
|
885
|
+
|
|
886
|
+
constructor(private readonly initial: BufferState) {}
|
|
887
|
+
|
|
888
|
+
async loadBuffer(): Promise<BufferState> {
|
|
889
|
+
return structuredClone(this.initial);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
blockNextSave(): void {
|
|
893
|
+
this.blockNext = true;
|
|
894
|
+
this.startedPromise = new Promise<void>((resolve) => {
|
|
895
|
+
this.signalStarted = resolve;
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
saveStarted(): Promise<void> {
|
|
900
|
+
return this.startedPromise ?? Promise.resolve();
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
releaseSave(): void {
|
|
904
|
+
this.release?.();
|
|
905
|
+
this.release = null;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
async saveBuffer(state: BufferState): Promise<void> {
|
|
909
|
+
this.saveCount += 1;
|
|
910
|
+
const snapshot = structuredClone(state);
|
|
911
|
+
if (this.blockNext) {
|
|
912
|
+
this.blockNext = false;
|
|
913
|
+
const gate = new Promise<void>((resolve) => {
|
|
914
|
+
this.release = resolve;
|
|
915
|
+
});
|
|
916
|
+
this.signalStarted?.();
|
|
917
|
+
await gate;
|
|
918
|
+
}
|
|
919
|
+
this.saved = snapshot;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
test("debounce on: a turn recorded around a forced flush is not dropped by the flush's clear (PR #2016)", async () => {
|
|
924
|
+
// Issue #1909 PR #2016 review: flushPendingSave used to clear
|
|
925
|
+
// pendingSave/firstPendingAtMs AFTER the serialized write mutation resolved,
|
|
926
|
+
// i.e. OUTSIDE the serializer. A turn recorded around that flush re-arms a
|
|
927
|
+
// debounced save (pendingSave = true); if the flush's late clear then wiped
|
|
928
|
+
// that flag, the interleaved turn's own scheduled flush would early-return
|
|
929
|
+
// and its persistence would be lost. The fix makes write + clear atomic on
|
|
930
|
+
// the existing serializer mutex. This drives the interleave deterministically
|
|
931
|
+
// and proves BOTH the pre-flush turn and the interleaved turn reach disk.
|
|
932
|
+
const storage = new GatedSaveStorage(emptyBufferState());
|
|
933
|
+
const buffer = new SmartBuffer(
|
|
934
|
+
parseConfig({ bufferSaveDebounceMs: 10_000, triggerMode: "smart", bufferMaxTurns: 10_000 }),
|
|
935
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
936
|
+
);
|
|
937
|
+
|
|
938
|
+
// Pre-flush turn: schedules a debounced save (pendingSave = true, timer armed).
|
|
939
|
+
assert.equal(
|
|
940
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "pre-flush")),
|
|
941
|
+
"keep_buffering",
|
|
942
|
+
);
|
|
943
|
+
|
|
944
|
+
// Force a flush whose write blocks mid-flight, holding the serializer.
|
|
945
|
+
storage.blockNextSave();
|
|
946
|
+
const flushP = buffer.flushPendingSave();
|
|
947
|
+
await storage.saveStarted();
|
|
948
|
+
|
|
949
|
+
// Interleave a turn while the flush write is in flight. It queues behind the
|
|
950
|
+
// flush's write mutation on the serializer and records only after it settles.
|
|
951
|
+
const addP = buffer.addTurn("thread-a", makeTurn("thread-a", "post-flush"));
|
|
952
|
+
|
|
953
|
+
// Let the flush write land and everything settle.
|
|
954
|
+
storage.releaseSave();
|
|
955
|
+
await Promise.all([flushP, addP]);
|
|
956
|
+
|
|
957
|
+
const internals = buffer as unknown as DebouncedBufferInternals;
|
|
958
|
+
assert.deepEqual(
|
|
959
|
+
buffer.getTurns("thread-a").map((t) => t.content),
|
|
960
|
+
["pre-flush", "post-flush"],
|
|
961
|
+
"both turns are held in memory",
|
|
962
|
+
);
|
|
963
|
+
assert.equal(
|
|
964
|
+
internals.pendingSave,
|
|
965
|
+
true,
|
|
966
|
+
"the interleaved turn's debounced save survives the flush's clear (owns its own flush)",
|
|
967
|
+
);
|
|
968
|
+
|
|
969
|
+
// The interleaved turn's pending save must still land — the flush's clear must
|
|
970
|
+
// not have silently dropped it.
|
|
971
|
+
await buffer.flushPendingSave();
|
|
972
|
+
assert.deepEqual(
|
|
973
|
+
storage.saved?.entries?.["thread-a"]?.turns.map((t) => t.content) ?? [],
|
|
974
|
+
["pre-flush", "post-flush"],
|
|
975
|
+
"the pre-flush turn and the interleaved turn both persist",
|
|
976
|
+
);
|
|
977
|
+
assert.equal(internals.pendingSave, false, "pending is cleared only after the durable write");
|
|
978
|
+
});
|
|
@@ -22,6 +22,7 @@ import type { BufferState, BufferTurn } from "./types.js";
|
|
|
22
22
|
|
|
23
23
|
class FakeStorage {
|
|
24
24
|
public saved: BufferState | null = null;
|
|
25
|
+
public saveCount = 0;
|
|
25
26
|
|
|
26
27
|
constructor(private readonly initial: BufferState) {}
|
|
27
28
|
|
|
@@ -30,6 +31,7 @@ class FakeStorage {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
async saveBuffer(state: BufferState): Promise<void> {
|
|
34
|
+
this.saveCount += 1;
|
|
33
35
|
this.saved = structuredClone(state);
|
|
34
36
|
}
|
|
35
37
|
}
|
|
@@ -355,6 +357,7 @@ async function assertProbeRejectionHandled(
|
|
|
355
357
|
bufferSurpriseThreshold: 0.35,
|
|
356
358
|
bufferMaxTurns: 5,
|
|
357
359
|
triggerMode: "smart",
|
|
360
|
+
bufferSaveDebounceMs: 0,
|
|
358
361
|
});
|
|
359
362
|
const buffer = new SmartBuffer(config, storage as any, probe);
|
|
360
363
|
|
|
@@ -476,6 +479,7 @@ test("flag on: probe that never resolves is timed out, turn is still saved", asy
|
|
|
476
479
|
bufferSurpriseProbeTimeoutMs: 30,
|
|
477
480
|
bufferMaxTurns: 5,
|
|
478
481
|
triggerMode: "smart",
|
|
482
|
+
bufferSaveDebounceMs: 0,
|
|
479
483
|
});
|
|
480
484
|
const buffer = new SmartBuffer(config, storage as any, probe);
|
|
481
485
|
|
|
@@ -523,6 +527,7 @@ test("flag on: slow probe does not hold the buffer mutation queue", async () =>
|
|
|
523
527
|
bufferSurpriseProbeTimeoutMs: 1000,
|
|
524
528
|
bufferMaxTurns: 5,
|
|
525
529
|
triggerMode: "smart",
|
|
530
|
+
bufferSaveDebounceMs: 0,
|
|
526
531
|
});
|
|
527
532
|
const buffer = new SmartBuffer(config, storage as any, probe);
|
|
528
533
|
|
|
@@ -750,3 +755,39 @@ test("flag on: stale snapshot clears do not mark live turns as freshly extracted
|
|
|
750
755
|
"a skipped stale-snapshot clear must not advance extraction metadata",
|
|
751
756
|
);
|
|
752
757
|
});
|
|
758
|
+
|
|
759
|
+
// ---------------------------------------------------------------------------
|
|
760
|
+
// Issue #1909 (review finding 1) — surprise promotion forces a durable flush
|
|
761
|
+
// ---------------------------------------------------------------------------
|
|
762
|
+
|
|
763
|
+
test("debounce on: surprise-promoted extract_now flushes the buffer before extraction", async () => {
|
|
764
|
+
const storage = new FakeStorage(emptyBuffer());
|
|
765
|
+
const probe = fixedScoreProbe(0.99); // promotes keep_buffering -> extract_now
|
|
766
|
+
const config = parseConfig({
|
|
767
|
+
bufferSurpriseTriggerEnabled: true,
|
|
768
|
+
bufferSurpriseThreshold: 0.35,
|
|
769
|
+
// High turn cap so the built-in trigger keeps buffering; only the surprise
|
|
770
|
+
// probe promotes. Large debounce so a scheduled save would NOT have landed.
|
|
771
|
+
bufferMaxTurns: 100,
|
|
772
|
+
triggerMode: "smart",
|
|
773
|
+
bufferSaveDebounceMs: 10_000,
|
|
774
|
+
});
|
|
775
|
+
const buffer = new SmartBuffer(
|
|
776
|
+
config,
|
|
777
|
+
storage as unknown as ConstructorParameters<typeof SmartBuffer>[1],
|
|
778
|
+
probe,
|
|
779
|
+
);
|
|
780
|
+
|
|
781
|
+
const outcome = await buffer.addTurnWithOutcome("sess-1", makeTurn("sess-1", "novel turn"));
|
|
782
|
+
assert.equal(outcome.decision, "extract_now", "surprise promotes the turn");
|
|
783
|
+
assert.equal(
|
|
784
|
+
storage.saveCount,
|
|
785
|
+
1,
|
|
786
|
+
"the buffer was flushed to disk EXACTLY once before extraction (timer cancelled, single flush)",
|
|
787
|
+
);
|
|
788
|
+
assert.equal(
|
|
789
|
+
storage.saved?.entries?.["sess-1"]?.turns.length,
|
|
790
|
+
1,
|
|
791
|
+
"the persisted buffer contains the turn that triggered extraction",
|
|
792
|
+
);
|
|
793
|
+
});
|