@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
package/src/access-boundary.ts
CHANGED
|
@@ -16,8 +16,14 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { z } from "zod";
|
|
19
|
+
import { EngramAccessForbiddenError } from "./access-errors.js";
|
|
19
20
|
import { EngramAccessInputError, type EngramAccessService } from "./access-service.js";
|
|
20
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
assertFleetWideOperationAllowed,
|
|
23
|
+
assertOperationAllowed,
|
|
24
|
+
capabilityAllowsOp,
|
|
25
|
+
tokenCapabilityStore,
|
|
26
|
+
} from "./access-token-capabilities.js";
|
|
21
27
|
import { expandTildePath } from "./utils/path.js";
|
|
22
28
|
|
|
23
29
|
// ---------------------------------------------------------------------------
|
|
@@ -63,6 +69,7 @@ export const OPERATION_NAMES = [
|
|
|
63
69
|
"set_coding_context",
|
|
64
70
|
"recall_tier_explain",
|
|
65
71
|
"recall_xray",
|
|
72
|
+
"namespace_writable",
|
|
66
73
|
"wearables_status",
|
|
67
74
|
"wearables_sync",
|
|
68
75
|
"transcript_day",
|
|
@@ -235,6 +242,17 @@ export interface OperationSpec<In, Out> {
|
|
|
235
242
|
* (cron, internal callers, no capability record) are unaffected (issue #1850).
|
|
236
243
|
*/
|
|
237
244
|
readonly fleetWide?: boolean;
|
|
245
|
+
/**
|
|
246
|
+
* Alternate op allow-list: when set, the token may invoke this operation if
|
|
247
|
+
* its ops allow-list permits ANY of these ops (instead of the default rule
|
|
248
|
+
* that requires the op's own {@link name}). Lets a read-only diagnostic be
|
|
249
|
+
* granted by the write ops it diagnoses — e.g. `namespace_writable` is
|
|
250
|
+
* runnable by any token permitted to `observe`/`memory_store`, so a token
|
|
251
|
+
* minted before the diagnostic op existed can still call it. Unrestricted /
|
|
252
|
+
* legacy tokens (no ops axis) are unaffected. Keeps the boundary and any HTTP
|
|
253
|
+
* transport for the same op enforcing ONE policy.
|
|
254
|
+
*/
|
|
255
|
+
readonly allowedByOps?: readonly OperationName[];
|
|
238
256
|
}
|
|
239
257
|
|
|
240
258
|
export interface BoundOperation<In = unknown, Out = unknown> {
|
|
@@ -408,7 +426,18 @@ export function defineOperation<In, Out>(spec: OperationSpec<In, Out>): BoundOpe
|
|
|
408
426
|
// unrestricted. Default-deny ONLY when an ops axis is present — legacy
|
|
409
427
|
// tokens (absent record) and explicit-unrestricted new tokens are
|
|
410
428
|
// unaffected.
|
|
411
|
-
|
|
429
|
+
// When the op declares alternate grant ops, permit any of them (so the
|
|
430
|
+
// batch/MCP path matches an HTTP transport that relaxes the same op);
|
|
431
|
+
// otherwise the token must carry the op's own name. Unrestricted/legacy
|
|
432
|
+
// tokens pass either way (capabilityAllowsOp is true when no ops axis).
|
|
433
|
+
if (spec.allowedByOps && spec.allowedByOps.length > 0) {
|
|
434
|
+
const store = tokenCapabilityStore.getStore();
|
|
435
|
+
if (!spec.allowedByOps.some((op) => capabilityAllowsOp(store, op))) {
|
|
436
|
+
throw new EngramAccessForbiddenError(`token is not permitted to call operation: ${spec.name}`);
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
assertOperationAllowed(tokenCapabilityStore.getStore(), spec.name);
|
|
440
|
+
}
|
|
412
441
|
// Fleet-wide / global maintenance ops (issue #1850 round 10): these run
|
|
413
442
|
// across all namespaces with no `namespace` arg, so the tools/call
|
|
414
443
|
// effective-namespace gate never fires. A namespace-SCOPED token must not
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
recordCitationUsage,
|
|
6
|
+
type CitationUsageDependencies,
|
|
7
|
+
} from "./access-citation.js";
|
|
8
|
+
|
|
9
|
+
test("recordCitationUsage matches each citation to its cited path before fallback", async () => {
|
|
10
|
+
let tracked: { ids: string[]; paths: string[] } | null = null;
|
|
11
|
+
const deps: CitationUsageDependencies = {
|
|
12
|
+
resolveNamespace: () => "main",
|
|
13
|
+
getStorage: async () => ({
|
|
14
|
+
findExistingMemoryPaths: async () =>
|
|
15
|
+
new Map([["same-id", ["facts/other/same-id.md", "facts/cited/same-id.md"]]]),
|
|
16
|
+
}),
|
|
17
|
+
trackMemoryAccess: (ids, paths) => {
|
|
18
|
+
tracked = { ids, paths };
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const result = await recordCitationUsage(deps, {
|
|
22
|
+
namespace: "main",
|
|
23
|
+
entries: [
|
|
24
|
+
{ path: "facts/cited/same-id.md", lineStart: 1, lineEnd: 1, note: "cited" },
|
|
25
|
+
{ path: "facts/other/same-id.md", lineStart: 1, lineEnd: 1, note: "other" },
|
|
26
|
+
],
|
|
27
|
+
rolloutIds: [],
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
assert.deepEqual(result, { submitted: 2, matched: 2 });
|
|
31
|
+
assert.deepEqual(tracked, {
|
|
32
|
+
ids: ["same-id", "same-id"],
|
|
33
|
+
paths: ["facts/cited/same-id.md", "facts/other/same-id.md"],
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("recordCitationUsage resolves each cited path before selecting storage", async () => {
|
|
38
|
+
const storageCalls: string[] = [];
|
|
39
|
+
let tracked: { ids: string[]; paths: string[]; namespaces: Array<string | undefined> } | null = null;
|
|
40
|
+
const deps: CitationUsageDependencies = {
|
|
41
|
+
resolveNamespace: () => "main",
|
|
42
|
+
resolveNamespaceForPath: async (path) =>
|
|
43
|
+
path.startsWith("namespaces/team/") ? "team" : "main",
|
|
44
|
+
getStorage: async (namespace) => {
|
|
45
|
+
storageCalls.push(namespace);
|
|
46
|
+
return {
|
|
47
|
+
findExistingMemoryPaths: async (ids) =>
|
|
48
|
+
new Map(ids.map((id) => [id, [`${namespace}/${id}.md`]])),
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
trackMemoryAccess: (ids, paths, namespaces) => {
|
|
52
|
+
tracked = { ids, paths, namespaces: namespaces ?? [] };
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const result = await recordCitationUsage(deps, {
|
|
57
|
+
namespace: "main",
|
|
58
|
+
entries: [
|
|
59
|
+
{ path: "namespaces/team/facts/shared.md", lineStart: 1, lineEnd: 1, note: "team" },
|
|
60
|
+
{ path: "facts/main.md", lineStart: 1, lineEnd: 1, note: "main" },
|
|
61
|
+
],
|
|
62
|
+
rolloutIds: [],
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
assert.deepEqual(result, { submitted: 2, matched: 2 });
|
|
66
|
+
assert.deepEqual(storageCalls, ["team", "main"]);
|
|
67
|
+
assert.deepEqual(tracked, {
|
|
68
|
+
ids: ["shared", "main"],
|
|
69
|
+
paths: ["team/shared.md", "main/main.md"],
|
|
70
|
+
namespaces: ["team", "main"],
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { log } from "./logger.js";
|
|
2
|
+
|
|
3
|
+
export interface CitationUsageRequest {
|
|
4
|
+
sessionId?: string;
|
|
5
|
+
namespace?: string;
|
|
6
|
+
authenticatedPrincipal?: string;
|
|
7
|
+
entries: Array<{ path: string; lineStart: number; lineEnd: number; note: string }>;
|
|
8
|
+
rolloutIds: string[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CitationStorage {
|
|
12
|
+
findExistingMemoryPaths(
|
|
13
|
+
ids: string[],
|
|
14
|
+
preferredPaths?: Map<string, string[]>,
|
|
15
|
+
): Promise<Map<string, string[]>>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CitationUsageDependencies {
|
|
19
|
+
resolveNamespace: (
|
|
20
|
+
namespace: string | undefined,
|
|
21
|
+
sessionId: string | undefined,
|
|
22
|
+
authenticatedPrincipal: string | undefined,
|
|
23
|
+
) => string;
|
|
24
|
+
resolveNamespaceForPath?: (
|
|
25
|
+
path: string,
|
|
26
|
+
fallbackNamespace: string,
|
|
27
|
+
sessionId: string | undefined,
|
|
28
|
+
authenticatedPrincipal: string | undefined,
|
|
29
|
+
) => Promise<string>;
|
|
30
|
+
getStorage: (namespace: string) => Promise<CitationStorage>;
|
|
31
|
+
trackMemoryAccess: (
|
|
32
|
+
memoryIds: string[],
|
|
33
|
+
memoryPaths: string[],
|
|
34
|
+
memoryNamespaces?: Array<string | undefined>,
|
|
35
|
+
) => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface CitationUsageResult {
|
|
39
|
+
submitted: number;
|
|
40
|
+
matched: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function recordCitationUsage(
|
|
44
|
+
deps: CitationUsageDependencies,
|
|
45
|
+
request: CitationUsageRequest,
|
|
46
|
+
): Promise<CitationUsageResult> {
|
|
47
|
+
if (request.entries.length === 0) return { submitted: 0, matched: 0 };
|
|
48
|
+
|
|
49
|
+
const fallbackNamespace = deps.resolveNamespace(
|
|
50
|
+
request.namespace,
|
|
51
|
+
request.sessionId,
|
|
52
|
+
request.authenticatedPrincipal,
|
|
53
|
+
);
|
|
54
|
+
const memoryEntries = (await Promise.all(
|
|
55
|
+
request.entries.map(async (entry) => {
|
|
56
|
+
const basename = entry.path.split(/[\\/]/).pop() ?? entry.path;
|
|
57
|
+
const id = basename.endsWith(".md") ? basename.slice(0, -3) : basename;
|
|
58
|
+
if (id.length === 0) return null;
|
|
59
|
+
const namespace = deps.resolveNamespaceForPath
|
|
60
|
+
? await deps.resolveNamespaceForPath(
|
|
61
|
+
entry.path,
|
|
62
|
+
fallbackNamespace,
|
|
63
|
+
request.sessionId,
|
|
64
|
+
request.authenticatedPrincipal,
|
|
65
|
+
)
|
|
66
|
+
: fallbackNamespace;
|
|
67
|
+
// Strip the resolved namespace prefix so citedPath is storage-relative for
|
|
68
|
+
// both preferred-path matching and the exact-match lookup below. Namespace
|
|
69
|
+
// names may contain "/", which the storage helper cannot strip alone (#2020).
|
|
70
|
+
const citedPath =
|
|
71
|
+
namespace && entry.path.startsWith(`${namespace}/`)
|
|
72
|
+
? entry.path.slice(namespace.length + 1)
|
|
73
|
+
: entry.path;
|
|
74
|
+
return { id, citedPath, namespace };
|
|
75
|
+
}),
|
|
76
|
+
)).filter(
|
|
77
|
+
(
|
|
78
|
+
entry,
|
|
79
|
+
): entry is { id: string; citedPath: string; namespace: string } =>
|
|
80
|
+
entry !== null,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (memoryEntries.length === 0) return { submitted: 0, matched: 0 };
|
|
84
|
+
|
|
85
|
+
const matchedEntries: Array<{
|
|
86
|
+
id: string;
|
|
87
|
+
path: string;
|
|
88
|
+
namespace: string;
|
|
89
|
+
}> = [];
|
|
90
|
+
const entriesByNamespace = new Map<string, typeof memoryEntries>();
|
|
91
|
+
for (const entry of memoryEntries) {
|
|
92
|
+
const entries = entriesByNamespace.get(entry.namespace) ?? [];
|
|
93
|
+
entries.push(entry);
|
|
94
|
+
entriesByNamespace.set(entry.namespace, entries);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const [namespace, namespaceEntries] of entriesByNamespace) {
|
|
98
|
+
const storage = await deps.getStorage(namespace);
|
|
99
|
+
const ids = [...new Set(namespaceEntries.map((entry) => entry.id))];
|
|
100
|
+
const preferredPaths = new Map<string, string[]>();
|
|
101
|
+
for (const entry of namespaceEntries) {
|
|
102
|
+
const paths = preferredPaths.get(entry.id) ?? [];
|
|
103
|
+
paths.push(entry.citedPath);
|
|
104
|
+
preferredPaths.set(entry.id, paths);
|
|
105
|
+
}
|
|
106
|
+
const pathsById = await storage.findExistingMemoryPaths(ids, preferredPaths);
|
|
107
|
+
const remainingPathsById = new Map(
|
|
108
|
+
Array.from(pathsById.entries()).map(([id, paths]) => [id, [...paths]]),
|
|
109
|
+
);
|
|
110
|
+
for (const entry of namespaceEntries) {
|
|
111
|
+
const paths = remainingPathsById.get(entry.id);
|
|
112
|
+
if (!paths || paths.length === 0) continue;
|
|
113
|
+
const preferredIndex = paths.indexOf(entry.citedPath);
|
|
114
|
+
const pathIndex = preferredIndex >= 0 ? preferredIndex : 0;
|
|
115
|
+
const [memoryPath] = paths.splice(pathIndex, 1);
|
|
116
|
+
if (memoryPath) {
|
|
117
|
+
matchedEntries.push({
|
|
118
|
+
id: entry.id,
|
|
119
|
+
path: memoryPath,
|
|
120
|
+
namespace,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (matchedEntries.length > 0) {
|
|
127
|
+
try {
|
|
128
|
+
deps.trackMemoryAccess(
|
|
129
|
+
matchedEntries.map((entry) => entry.id),
|
|
130
|
+
matchedEntries.map((entry) => entry.path),
|
|
131
|
+
matchedEntries.map((entry) => entry.namespace),
|
|
132
|
+
);
|
|
133
|
+
} catch {
|
|
134
|
+
log.debug("citation usage tracking: failed to record access for cited memories");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return { submitted: memoryEntries.length, matched: matchedEntries.length };
|
|
139
|
+
}
|
package/src/access-errors.ts
CHANGED
|
@@ -1,2 +1,23 @@
|
|
|
1
1
|
/** Authenticated caller lacks the required authorization (HTTP 403). */
|
|
2
2
|
export class EngramAccessForbiddenError extends Error {}
|
|
3
|
+
|
|
4
|
+
/** Invalid caller input (HTTP 400). */
|
|
5
|
+
export class EngramAccessInputError extends Error {}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A write rejected by the namespace write-ACL (issue #1888). Subclasses
|
|
9
|
+
* EngramAccessInputError so every existing catch/HTTP-400 mapping still
|
|
10
|
+
* applies, but carries the attempted namespace + principal so the observe/
|
|
11
|
+
* write surfaces can dead-letter the payload before re-throwing (fail-closed
|
|
12
|
+
* placement is unchanged; only the destroyed-payload behavior is fixed).
|
|
13
|
+
*/
|
|
14
|
+
export class NamespaceNotWritableError extends EngramAccessInputError {
|
|
15
|
+
constructor(
|
|
16
|
+
readonly attemptedNamespace: string,
|
|
17
|
+
readonly principal: string | undefined,
|
|
18
|
+
message?: string
|
|
19
|
+
) {
|
|
20
|
+
super(message ?? `namespace is not writable: ${attemptedNamespace}`);
|
|
21
|
+
this.name = "NamespaceNotWritableError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
6
|
+
import {
|
|
7
|
+
AccessIdempotencyStore,
|
|
8
|
+
hashAccessIdempotencyPayload,
|
|
9
|
+
} from "./access-idempotency.js";
|
|
10
|
+
import {
|
|
11
|
+
buildAccessWriteRequestFingerprint,
|
|
12
|
+
buildObserveRequestFingerprint,
|
|
13
|
+
} from "./write-envelope.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Issue #1989 PR3 — fingerprint byte-parity safety net.
|
|
17
|
+
*
|
|
18
|
+
* The access surfaces' idempotency hashes are persisted indefinitely
|
|
19
|
+
* (AccessIdempotencyStore: last-512 LRU, no time TTL). The shared builders
|
|
20
|
+
* MUST reproduce the historical inline payload literals exactly, or every
|
|
21
|
+
* stored key silently stops replaying / starts conflicting after upgrade.
|
|
22
|
+
*
|
|
23
|
+
* The `legacy*` literals below are verbatim copies of the inline objects
|
|
24
|
+
* that lived at the call sites before PR3 (access-observe-write-surface.ts
|
|
25
|
+
* memoryStore/suggestionSubmit, access-service.ts peek twins and observe).
|
|
26
|
+
* Do NOT "sync" them with the builders — their whole point is to pin the
|
|
27
|
+
* historical shape.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
type WriteRequestish = {
|
|
31
|
+
content: string;
|
|
32
|
+
category?: string;
|
|
33
|
+
confidence?: number;
|
|
34
|
+
tags?: string[];
|
|
35
|
+
entityRef?: string;
|
|
36
|
+
ttl?: string;
|
|
37
|
+
sourceReason?: string;
|
|
38
|
+
sourceConnector?: string;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function legacyWriteFingerprint(
|
|
42
|
+
request: WriteRequestish,
|
|
43
|
+
namespace: string,
|
|
44
|
+
schemaVersion: number,
|
|
45
|
+
): Record<string, unknown> {
|
|
46
|
+
// Verbatim pre-PR3 shape — field order as it appeared in the source.
|
|
47
|
+
return {
|
|
48
|
+
schemaVersion,
|
|
49
|
+
content: request.content,
|
|
50
|
+
category: request.category,
|
|
51
|
+
confidence: request.confidence,
|
|
52
|
+
namespace,
|
|
53
|
+
tags: request.tags,
|
|
54
|
+
entityRef: request.entityRef,
|
|
55
|
+
ttl: request.ttl,
|
|
56
|
+
sourceReason: request.sourceReason,
|
|
57
|
+
sourceConnector: request.sourceConnector,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const FULL_WRITE: WriteRequestish = {
|
|
62
|
+
content: "User prefers dark mode",
|
|
63
|
+
category: "preference",
|
|
64
|
+
confidence: 0.8,
|
|
65
|
+
tags: ["ui", "preference", "ui"],
|
|
66
|
+
entityRef: "person-test-user",
|
|
67
|
+
ttl: "2027-01-01T00:00:00.000Z",
|
|
68
|
+
sourceReason: "operator request",
|
|
69
|
+
sourceConnector: "cli",
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const SPARSE_WRITE: WriteRequestish = {
|
|
73
|
+
content: "Sparse fact with every optional absent",
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
test("memory_store/suggestion_submit fingerprints hash identically to the pre-PR3 literals", () => {
|
|
77
|
+
for (const request of [FULL_WRITE, SPARSE_WRITE]) {
|
|
78
|
+
for (const operation of ["memory_store", "suggestion_submit"] as const) {
|
|
79
|
+
const legacy = hashAccessIdempotencyPayload({
|
|
80
|
+
operation,
|
|
81
|
+
request: legacyWriteFingerprint(request, "default", 1),
|
|
82
|
+
});
|
|
83
|
+
const migrated = hashAccessIdempotencyPayload({
|
|
84
|
+
operation,
|
|
85
|
+
request: buildAccessWriteRequestFingerprint({
|
|
86
|
+
schemaVersion: 1,
|
|
87
|
+
namespace: "default",
|
|
88
|
+
content: request.content,
|
|
89
|
+
category: request.category,
|
|
90
|
+
confidence: request.confidence,
|
|
91
|
+
tags: request.tags,
|
|
92
|
+
entityRef: request.entityRef,
|
|
93
|
+
ttl: request.ttl,
|
|
94
|
+
sourceReason: request.sourceReason,
|
|
95
|
+
sourceConnector: request.sourceConnector,
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
assert.equal(migrated, legacy, `${operation} fingerprint diverged for ${request.content}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test("write fingerprints keep raw values: tag order and duplicates are identity", () => {
|
|
104
|
+
const base = {
|
|
105
|
+
schemaVersion: 1,
|
|
106
|
+
namespace: "default",
|
|
107
|
+
content: "same content",
|
|
108
|
+
};
|
|
109
|
+
const a = hashAccessIdempotencyPayload(
|
|
110
|
+
buildAccessWriteRequestFingerprint({ ...base, tags: ["b", "a"] }),
|
|
111
|
+
);
|
|
112
|
+
const b = hashAccessIdempotencyPayload(
|
|
113
|
+
buildAccessWriteRequestFingerprint({ ...base, tags: ["a", "b"] }),
|
|
114
|
+
);
|
|
115
|
+
// The legacy shape hashed the RAW tags array; preserving stored state
|
|
116
|
+
// means preserving that (documented per-surface quirk until a versioned
|
|
117
|
+
// payload migration; the envelope's v1 payload sorts tags instead).
|
|
118
|
+
assert.notEqual(a, b, "raw tag order must remain identity, matching stored pre-PR3 hashes");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("observe fingerprint hashes identically to the pre-PR3 literal", () => {
|
|
122
|
+
const request = {
|
|
123
|
+
sessionKey: "agent:main:test",
|
|
124
|
+
messages: [
|
|
125
|
+
{ role: "user", content: "hello" },
|
|
126
|
+
{ role: "assistant", content: "hi there" },
|
|
127
|
+
],
|
|
128
|
+
namespace: undefined as string | undefined,
|
|
129
|
+
skipExtraction: false,
|
|
130
|
+
authenticatedPrincipal: "operator",
|
|
131
|
+
cwd: "/home/user/project",
|
|
132
|
+
projectTag: "acme",
|
|
133
|
+
sourceConnector: undefined as string | undefined,
|
|
134
|
+
};
|
|
135
|
+
const codingContext = { projectId: "origin:abc", branch: "main" };
|
|
136
|
+
for (const effective of [codingContext, null]) {
|
|
137
|
+
const legacy = hashAccessIdempotencyPayload({
|
|
138
|
+
operation: "observe",
|
|
139
|
+
request: {
|
|
140
|
+
sessionKey: request.sessionKey,
|
|
141
|
+
messages: request.messages,
|
|
142
|
+
namespace: request.namespace,
|
|
143
|
+
skipExtraction: request.skipExtraction,
|
|
144
|
+
authenticatedPrincipal: request.authenticatedPrincipal,
|
|
145
|
+
cwd: request.cwd,
|
|
146
|
+
projectTag: request.projectTag,
|
|
147
|
+
effectiveCodingContext: effective ?? null,
|
|
148
|
+
sourceConnector: request.sourceConnector,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
const migrated = hashAccessIdempotencyPayload({
|
|
152
|
+
operation: "observe",
|
|
153
|
+
request: buildObserveRequestFingerprint({
|
|
154
|
+
sessionKey: request.sessionKey,
|
|
155
|
+
messages: request.messages,
|
|
156
|
+
namespace: request.namespace,
|
|
157
|
+
skipExtraction: request.skipExtraction,
|
|
158
|
+
authenticatedPrincipal: request.authenticatedPrincipal,
|
|
159
|
+
cwd: request.cwd,
|
|
160
|
+
projectTag: request.projectTag,
|
|
161
|
+
effectiveCodingContext: effective ?? null,
|
|
162
|
+
sourceConnector: request.sourceConnector,
|
|
163
|
+
}),
|
|
164
|
+
});
|
|
165
|
+
assert.equal(migrated, legacy);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("stored idempotency state from before PR3 still replays after PR3 (state-file round-trip)", async () => {
|
|
170
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-idem-parity-"));
|
|
171
|
+
try {
|
|
172
|
+
const statePath = path.join(dir, "state", "access-idempotency.json");
|
|
173
|
+
const preUpgrade = new AccessIdempotencyStore(statePath);
|
|
174
|
+
// A pre-PR3 deployment recorded this response under the inline-literal hash.
|
|
175
|
+
const preHash = hashAccessIdempotencyPayload({
|
|
176
|
+
operation: "memory_store",
|
|
177
|
+
request: legacyWriteFingerprint(FULL_WRITE, "default", 1),
|
|
178
|
+
});
|
|
179
|
+
const storedResponse = { operation: "memory_store", memoryId: "fact-pre-upgrade", accepted: true };
|
|
180
|
+
await preUpgrade.put("idem-key-1", preHash, storedResponse);
|
|
181
|
+
|
|
182
|
+
// Post-upgrade process: fresh store instance over the same state file,
|
|
183
|
+
// hash computed through the PR3 builder.
|
|
184
|
+
const postUpgrade = new AccessIdempotencyStore(statePath);
|
|
185
|
+
const postHash = hashAccessIdempotencyPayload({
|
|
186
|
+
operation: "memory_store",
|
|
187
|
+
request: buildAccessWriteRequestFingerprint({
|
|
188
|
+
schemaVersion: 1,
|
|
189
|
+
namespace: "default",
|
|
190
|
+
...FULL_WRITE,
|
|
191
|
+
}),
|
|
192
|
+
});
|
|
193
|
+
const replay = await postUpgrade.get("idem-key-1", postHash);
|
|
194
|
+
assert.equal(replay.conflict, false, "same request must not conflict across the upgrade");
|
|
195
|
+
assert.deepEqual(replay.response, storedResponse, "pre-upgrade response must replay");
|
|
196
|
+
|
|
197
|
+
// And a DIFFERENT request on the same key still conflicts (hash still discriminates).
|
|
198
|
+
const differentHash = hashAccessIdempotencyPayload({
|
|
199
|
+
operation: "memory_store",
|
|
200
|
+
request: buildAccessWriteRequestFingerprint({
|
|
201
|
+
schemaVersion: 1,
|
|
202
|
+
namespace: "default",
|
|
203
|
+
content: "entirely different content",
|
|
204
|
+
}),
|
|
205
|
+
});
|
|
206
|
+
const conflict = await postUpgrade.get("idem-key-1", differentHash);
|
|
207
|
+
assert.equal(conflict.conflict, true, "different request on the same key must conflict");
|
|
208
|
+
} finally {
|
|
209
|
+
await rm(dir, { recursive: true, force: true });
|
|
210
|
+
}
|
|
211
|
+
});
|
|
@@ -4,6 +4,10 @@ import test from "node:test";
|
|
|
4
4
|
|
|
5
5
|
import { EngramAccessHttpServer } from "./access-http.js";
|
|
6
6
|
import { EngramAccessService, type EngramAccessRecallRequest } from "./access-service.js";
|
|
7
|
+
import {
|
|
8
|
+
type RecallCoordinatorHost,
|
|
9
|
+
withRecallConcurrency,
|
|
10
|
+
} from "./access-recall-concurrency.js";
|
|
7
11
|
|
|
8
12
|
function deferred<T = void>(): {
|
|
9
13
|
promise: Promise<T>;
|
|
@@ -92,66 +96,75 @@ test("HTTP recall aborts in-flight work when the client disconnects", async () =
|
|
|
92
96
|
}
|
|
93
97
|
});
|
|
94
98
|
|
|
95
|
-
test("a
|
|
99
|
+
test("a queued recall rejects immediately on abort — before the holder releases — and never starts", async () => {
|
|
96
100
|
const firstStarted = deferred<void>();
|
|
97
101
|
const releaseFirst = deferred<void>();
|
|
98
102
|
let secondStarted = false;
|
|
99
103
|
const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
|
|
100
104
|
const lockHost = service as unknown as {
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
recallSemaphores: Map<string, unknown>;
|
|
106
|
+
orchestrator: { config: Record<string, unknown> };
|
|
107
|
+
withRecallConcurrency<T>(
|
|
103
108
|
principal: string,
|
|
104
109
|
abortSignal: AbortSignal | undefined,
|
|
105
|
-
operation: () => Promise<T>,
|
|
110
|
+
operation: (queueWaitMs: number) => Promise<T>,
|
|
106
111
|
): Promise<T>;
|
|
107
112
|
};
|
|
108
|
-
lockHost.
|
|
113
|
+
lockHost.recallSemaphores = new Map();
|
|
114
|
+
// limit=1 => the second recall must queue behind the first.
|
|
115
|
+
lockHost.orchestrator = { config: { recallMaxConcurrentPerPrincipal: 1 } };
|
|
109
116
|
|
|
110
|
-
const first = lockHost
|
|
117
|
+
const first = withRecallConcurrency(lockHost as unknown as RecallCoordinatorHost, "principal", undefined, async () => {
|
|
111
118
|
firstStarted.resolve();
|
|
112
119
|
await releaseFirst.promise;
|
|
113
120
|
});
|
|
114
121
|
await firstStarted.promise;
|
|
115
122
|
|
|
116
123
|
const controller = new AbortController();
|
|
117
|
-
const second = lockHost
|
|
124
|
+
const second = withRecallConcurrency(lockHost as unknown as RecallCoordinatorHost, "principal", controller.signal, async () => {
|
|
118
125
|
secondStarted = true;
|
|
119
126
|
});
|
|
120
127
|
controller.abort();
|
|
121
|
-
releaseFirst.resolve();
|
|
122
128
|
|
|
123
|
-
|
|
129
|
+
// The queued recall rejects on abort WITHOUT waiting for the holder to
|
|
130
|
+
// release — the #1906 behavior change (the old width-1 lock only re-checked
|
|
131
|
+
// the abort signal after acquiring). The holder is still held here.
|
|
124
132
|
await assert.rejects(waitFor(second), (error: Error) => error.name === "AbortError");
|
|
125
133
|
assert.equal(secondStarted, false);
|
|
134
|
+
|
|
135
|
+
releaseFirst.resolve();
|
|
136
|
+
await first;
|
|
126
137
|
});
|
|
127
138
|
|
|
128
|
-
test("an aborted queued recall does not poison the principal
|
|
139
|
+
test("an aborted queued recall does not poison the per-principal recall lane", async () => {
|
|
129
140
|
const firstStarted = deferred<void>();
|
|
130
141
|
const releaseFirst = deferred<void>();
|
|
131
142
|
let secondStarted = false;
|
|
132
143
|
let thirdStarted = false;
|
|
133
144
|
const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
|
|
134
145
|
const lockHost = service as unknown as {
|
|
135
|
-
|
|
136
|
-
|
|
146
|
+
recallSemaphores: Map<string, unknown>;
|
|
147
|
+
orchestrator: { config: Record<string, unknown> };
|
|
148
|
+
withRecallConcurrency<T>(
|
|
137
149
|
principal: string,
|
|
138
150
|
abortSignal: AbortSignal | undefined,
|
|
139
|
-
operation: () => Promise<T>,
|
|
151
|
+
operation: (queueWaitMs: number) => Promise<T>,
|
|
140
152
|
): Promise<T>;
|
|
141
153
|
};
|
|
142
|
-
lockHost.
|
|
154
|
+
lockHost.recallSemaphores = new Map();
|
|
155
|
+
lockHost.orchestrator = { config: { recallMaxConcurrentPerPrincipal: 1 } };
|
|
143
156
|
|
|
144
|
-
const first = lockHost
|
|
157
|
+
const first = withRecallConcurrency(lockHost as unknown as RecallCoordinatorHost, "principal", undefined, async () => {
|
|
145
158
|
firstStarted.resolve();
|
|
146
159
|
await releaseFirst.promise;
|
|
147
160
|
});
|
|
148
161
|
await firstStarted.promise;
|
|
149
162
|
|
|
150
163
|
const controller = new AbortController();
|
|
151
|
-
const second = lockHost
|
|
164
|
+
const second = withRecallConcurrency(lockHost as unknown as RecallCoordinatorHost, "principal", controller.signal, async () => {
|
|
152
165
|
secondStarted = true;
|
|
153
166
|
});
|
|
154
|
-
const third = lockHost
|
|
167
|
+
const third = withRecallConcurrency(lockHost as unknown as RecallCoordinatorHost, "principal", undefined, async () => {
|
|
155
168
|
thirdStarted = true;
|
|
156
169
|
});
|
|
157
170
|
controller.abort();
|
|
@@ -175,18 +188,24 @@ function makeRecallServiceProbe(): {
|
|
|
175
188
|
let capturedFingerprint: unknown;
|
|
176
189
|
let didStore = false;
|
|
177
190
|
const host = service as unknown as {
|
|
178
|
-
|
|
191
|
+
recallSemaphores: Map<string, unknown>;
|
|
192
|
+
recallInFlight: Map<string, unknown>;
|
|
179
193
|
orchestrator: { config: Record<string, unknown> };
|
|
180
194
|
resolveRequestPrincipal: () => string;
|
|
195
|
+
budget: { record: () => { allowed: boolean }; release: () => void };
|
|
181
196
|
executeRecall: () => Promise<{ response: Record<string, never>; budgetRecordPrincipal: null }>;
|
|
182
197
|
handleIdempotentRead: (options: {
|
|
183
198
|
requestFingerprint: unknown;
|
|
184
199
|
execute: () => Promise<Record<string, never>>;
|
|
185
200
|
}) => Promise<Record<string, never>>;
|
|
186
201
|
};
|
|
187
|
-
host.
|
|
188
|
-
host.
|
|
202
|
+
host.recallSemaphores = new Map();
|
|
203
|
+
host.recallInFlight = new Map();
|
|
204
|
+
host.orchestrator = {
|
|
205
|
+
config: { recallMaxConcurrentPerPrincipal: 4, recallSingleFlightEnabled: true },
|
|
206
|
+
};
|
|
189
207
|
host.resolveRequestPrincipal = () => "principal";
|
|
208
|
+
host.budget = { record: () => ({ allowed: true }), release: () => {} };
|
|
190
209
|
host.executeRecall = async () => {
|
|
191
210
|
await executeRecall();
|
|
192
211
|
return { response: {}, budgetRecordPrincipal: null };
|
|
@@ -221,7 +240,11 @@ test("recall excludes its abort signal from the idempotency fingerprint", async
|
|
|
221
240
|
);
|
|
222
241
|
});
|
|
223
242
|
|
|
224
|
-
test("recall
|
|
243
|
+
test("a keyed recall persists its completed result even when the caller disconnects (#1906 r5 #1)", async () => {
|
|
244
|
+
// The pipeline runs to completion; the caller aborts mid-flight. Idempotent
|
|
245
|
+
// persistence must be decoupled from the caller's connection, so the result
|
|
246
|
+
// IS stored (a retry of the key returns it) while the caller still sees the
|
|
247
|
+
// AbortError for its own disconnected request.
|
|
225
248
|
const probe = makeRecallServiceProbe();
|
|
226
249
|
const controller = new AbortController();
|
|
227
250
|
probe.setExecuteRecall(async () => {
|
|
@@ -236,5 +259,20 @@ test("recall does not store a result when the pipeline consumes an abort", async
|
|
|
236
259
|
}),
|
|
237
260
|
(error: Error) => error.name === "AbortError",
|
|
238
261
|
);
|
|
262
|
+
assert.equal(probe.stored(), true);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test("a keyed recall does not store when the pipeline itself throws", async () => {
|
|
266
|
+
// When the underlying pipeline fails/aborts (throws), nothing is persisted —
|
|
267
|
+
// a retry re-executes rather than replaying a failed result.
|
|
268
|
+
const probe = makeRecallServiceProbe();
|
|
269
|
+
probe.setExecuteRecall(async () => {
|
|
270
|
+
throw new Error("pipeline failed");
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
await assert.rejects(
|
|
274
|
+
probe.service.recall({ query: "boom", idempotencyKey: "boom-key" }),
|
|
275
|
+
/pipeline failed/,
|
|
276
|
+
);
|
|
239
277
|
assert.equal(probe.stored(), false);
|
|
240
278
|
});
|