@remnic/core 9.69.22 → 9.69.24
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/abstraction-nodes.js +3 -2
- package/dist/access-admin-ops-surface.d.ts +14 -12
- package/dist/access-admin-ops-surface.js +94 -91
- package/dist/access-authorization-probe.d.ts +14 -12
- package/dist/access-authorization-probe.js +95 -92
- package/dist/access-boundary.d.ts +14 -12
- package/dist/access-boundary.js +94 -91
- package/dist/access-citation-namespace.js +3 -3
- package/dist/access-cli.js +200 -195
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +2 -1
- package/dist/access-extraction-force-flush.d.ts +14 -12
- package/dist/access-extraction-force-flush.js +94 -91
- package/dist/access-health-types.d.ts +2 -1
- package/dist/access-http-briefing.d.ts +156 -0
- package/dist/access-http-briefing.js +233 -0
- package/dist/access-http-lcm-compaction.d.ts +14 -12
- package/dist/access-http-lifecycle-flush.d.ts +14 -12
- package/dist/access-http-offline-stream.d.ts +14 -12
- package/dist/access-http-query.d.ts +3 -2
- package/dist/access-http-query.js +96 -93
- package/dist/access-http.d.ts +15 -13
- package/dist/access-http.js +119 -114
- package/dist/access-identity-continuity-surface.d.ts +12 -10
- package/dist/access-identity-continuity-surface.js +94 -91
- package/dist/access-lcm-surface.d.ts +14 -12
- package/dist/access-lcm-surface.js +94 -91
- package/dist/access-mcp.d.ts +14 -12
- package/dist/access-mcp.js +105 -101
- package/dist/access-memory-search-fanout.d.ts +3 -2
- package/dist/{access-namespace-preflight-BMHhxoL9.d.ts → access-namespace-preflight-BsvmyENS.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +4 -3
- package/dist/access-namespace-preflight.js +94 -91
- package/dist/access-observe-transcript.d.ts +12 -10
- package/dist/access-observe-write-surface.d.ts +14 -12
- package/dist/access-observe-write-surface.js +94 -91
- package/dist/access-offline-manifest.d.ts +12 -10
- package/dist/access-offline-manifest.js +15 -15
- package/dist/access-operations-batch.js +99 -95
- package/dist/access-operations.d.ts +14 -12
- package/dist/access-operations.js +104 -100
- package/dist/access-recall-concurrency.d.ts +14 -12
- package/dist/access-recall-concurrency.js +94 -91
- package/dist/access-recall-response.d.ts +14 -12
- package/dist/access-recall-response.js +94 -91
- package/dist/access-recall-surface.d.ts +14 -12
- package/dist/access-recall-surface.js +94 -91
- package/dist/access-schema.js +8 -7
- package/dist/{access-service-BlsNXFwx.d.ts → access-service-DWdY9Mlk.d.ts} +7 -7
- package/dist/access-service-helpers.d.ts +14 -12
- package/dist/access-service.d.ts +14 -12
- package/dist/access-service.js +94 -91
- package/dist/access-surface-catalog.d.ts +14 -12
- package/dist/access-surface-catalog.js +97 -93
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +4 -3
- package/dist/action-confidence.d.ts +2 -1
- package/dist/active-memory-bridge.d.ts +2 -1
- package/dist/active-recall.d.ts +2 -1
- package/dist/active-recall.js +16 -13
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/ambient-provenance.d.ts +2 -1
- package/dist/artifact-search.d.ts +2 -1
- package/dist/{auto-sync-GRUJFD2F.js → auto-sync-WNGG2GC2.js} +9 -9
- package/dist/behavior-learner.d.ts +2 -1
- package/dist/behavior-signals.d.ts +2 -1
- package/dist/bootstrap.d.ts +12 -10
- package/dist/briefing-window.d.ts +3 -2
- package/dist/briefing.d.ts +3 -2
- package/dist/briefing.js +36 -36
- package/dist/buffer-surprise-report.d.ts +2 -1
- package/dist/buffer-turn-helpers.d.ts +2 -1
- package/dist/buffer.d.ts +3 -2
- package/dist/buffer.js +13 -13
- package/dist/bulk-import/index.d.ts +4 -3
- package/dist/calibration.d.ts +2 -1
- package/dist/calibration.js +2 -1
- package/dist/calibration.js.map +1 -1
- package/dist/capabilities.d.ts +2 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/{capsule-merge-SEHERWWP.js → capsule-merge-IPG4IOFP.js} +5 -5
- package/dist/{catalog-C1qHsGew.d.ts → catalog-CDZLyiXL.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +2 -1
- package/dist/causal-behavior.js +4 -3
- package/dist/causal-behavior.js.map +1 -1
- package/dist/causal-chain.js +4 -3
- package/dist/causal-consolidation.d.ts +2 -1
- package/dist/causal-consolidation.js +42 -42
- package/dist/causal-retrieval.js +4 -3
- package/dist/causal-retrieval.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +5 -2
- package/dist/causal-trajectory-graph.js +6 -2
- package/dist/causal-trajectory-graph.js.map +1 -1
- package/dist/causal-trajectory.js +3 -2
- package/dist/{chunk-KTVSPFCQ.js → chunk-22FVR2KE.js} +2 -2
- package/dist/{chunk-7Y5V3LAP.js → chunk-27QVNSQ3.js} +2 -2
- package/dist/{chunk-R7LY4YKF.js → chunk-2EKJDQZB.js} +2 -2
- package/dist/{chunk-FCATYKQA.js → chunk-2IOHTUP3.js} +263 -13
- package/dist/chunk-2IOHTUP3.js.map +1 -0
- package/dist/{chunk-HOUST5UX.js → chunk-2ITE4C2Z.js} +2 -2
- package/dist/{chunk-JOYC4RYC.js → chunk-2JVJ7UHC.js} +2 -2
- package/dist/{chunk-X2NFFBTO.js → chunk-2L5FSNPC.js} +7 -7
- package/dist/{chunk-DUAJKRR2.js → chunk-2SGLMP2E.js} +2 -2
- package/dist/{chunk-6FUMA6AA.js → chunk-2Z4GS5E6.js} +2 -2
- package/dist/{chunk-G6MXN2G5.js → chunk-37KUQPX4.js} +6 -6
- package/dist/{chunk-DDQQY2E3.js → chunk-3BTFBQLO.js} +7 -7
- package/dist/chunk-3BTFBQLO.js.map +1 -0
- package/dist/{chunk-UR6PBX2J.js → chunk-3K7V3HE6.js} +35 -60
- package/dist/chunk-3K7V3HE6.js.map +1 -0
- package/dist/{chunk-WKAXBXVA.js → chunk-3QQTXYZ6.js} +2 -2
- package/dist/{chunk-DJUKBGAD.js → chunk-46EST7JO.js} +5 -5
- package/dist/chunk-46EST7JO.js.map +1 -0
- package/dist/{chunk-4ZWCQJNM.js → chunk-46WM6JX2.js} +5 -5
- package/dist/{chunk-CASWJ2HM.js → chunk-46ZPIGWI.js} +3 -3
- package/dist/{chunk-HTIIXNJQ.js → chunk-4FIH6MPS.js} +6 -3
- package/dist/chunk-4FIH6MPS.js.map +1 -0
- package/dist/{chunk-MCA2X4WH.js → chunk-4IHBN6WU.js} +2 -2
- package/dist/{chunk-W7IGLX4G.js → chunk-4O6WRBGE.js} +7 -7
- package/dist/chunk-4O6WRBGE.js.map +1 -0
- package/dist/{chunk-FB7LAJQM.js → chunk-4TKJGOCJ.js} +2 -2
- package/dist/{chunk-H7BZBSP6.js → chunk-52II7PB6.js} +4 -4
- package/dist/{chunk-N4Y5T6VD.js → chunk-54WHLA65.js} +4 -4
- package/dist/chunk-56Y6EKZN.js +24 -0
- package/dist/chunk-56Y6EKZN.js.map +1 -0
- package/dist/{chunk-YVLENSNS.js → chunk-5ATKSPEQ.js} +2 -2
- package/dist/{chunk-OLT3YTDH.js → chunk-5FAGCOZD.js} +37 -24
- package/dist/chunk-5FAGCOZD.js.map +1 -0
- package/dist/{chunk-ZVZHG7AI.js → chunk-5UBH37SL.js} +3 -3
- package/dist/{chunk-N3WZU76A.js → chunk-66OJSCI6.js} +2 -2
- package/dist/{chunk-D35XLYQ7.js → chunk-6CVNSDCZ.js} +11 -11
- package/dist/{chunk-KA2HZCMG.js → chunk-6NXSYYGP.js} +2 -2
- package/dist/{chunk-2HIJHXB3.js → chunk-6WHJ2EAB.js} +2 -2
- package/dist/{chunk-ZZM476NV.js → chunk-6XL73HQ4.js} +4 -4
- package/dist/{chunk-EJ5RKUXW.js → chunk-AQ7SYDVO.js} +2 -2
- package/dist/{chunk-2Z3DG5CQ.js → chunk-B3O3IRZN.js} +2 -2
- package/dist/{chunk-P77QX3ID.js → chunk-B6O2YLUR.js} +21 -20
- package/dist/chunk-B6O2YLUR.js.map +1 -0
- package/dist/{chunk-RACZB5HT.js → chunk-BD7JTBYP.js} +4 -4
- package/dist/{chunk-I762GW7V.js → chunk-BLJWYCNO.js} +5 -5
- package/dist/{chunk-ACPCA4NO.js → chunk-BMWN7B3Y.js} +6 -6
- package/dist/chunk-BMWN7B3Y.js.map +1 -0
- package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-KK66P5GQ.js → chunk-C553ZTLF.js} +46 -48
- package/dist/chunk-C553ZTLF.js.map +1 -0
- package/dist/{chunk-GCASGYIO.js → chunk-C7HJ3NEI.js} +2 -2
- package/dist/{chunk-C24UZSFW.js → chunk-CEH2AFXG.js} +6 -6
- package/dist/{chunk-WVGXCBOC.js → chunk-D5F7TKMH.js} +2 -2
- package/dist/chunk-DGS34QSY.js +141 -0
- package/dist/chunk-DGS34QSY.js.map +1 -0
- package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/{chunk-2OXIPF3A.js → chunk-DZD3WGCD.js} +4 -4
- package/dist/{chunk-UMEOXLIZ.js → chunk-E2P7TZTF.js} +5 -5
- package/dist/{chunk-6FC3IZ26.js → chunk-EBA5DA77.js} +2 -2
- package/dist/{chunk-N7JK2RKG.js → chunk-EOQ6FSQP.js} +2 -2
- package/dist/chunk-EUT2WCWS.js +54 -0
- package/dist/chunk-EUT2WCWS.js.map +1 -0
- package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
- package/dist/{chunk-XDMI5VKE.js → chunk-FVOP3NT7.js} +2 -2
- package/dist/{chunk-NRLELHAY.js → chunk-G7NYVKD6.js} +2 -2
- package/dist/{chunk-B3W7GWQB.js → chunk-GHTSNGBZ.js} +2 -2
- package/dist/chunk-GKCXTSFF.js +17 -0
- package/dist/chunk-GKCXTSFF.js.map +1 -0
- package/dist/{chunk-LUDBXTBJ.js → chunk-H272ZPQ3.js} +5 -5
- package/dist/{chunk-SN4JXNLL.js → chunk-H3TKENU4.js} +2 -2
- package/dist/{chunk-4HYNMLT6.js → chunk-H4SEGIZY.js} +2 -2
- package/dist/{chunk-ACZN5ZXD.js → chunk-H54VWRPS.js} +13 -13
- package/dist/{chunk-HTP6XRUI.js → chunk-HM7RHKS4.js} +2 -2
- package/dist/{chunk-Z3SQEEB6.js → chunk-HWLIMQE2.js} +2 -2
- package/dist/{chunk-NQFCLAYT.js → chunk-ICKJ52PE.js} +99 -322
- package/dist/chunk-ICKJ52PE.js.map +1 -0
- package/dist/{chunk-2QSZNTDO.js → chunk-JBPKEARU.js} +7 -7
- package/dist/{chunk-DK6GMO6D.js → chunk-JEC4DVM3.js} +16 -16
- package/dist/chunk-JEC4DVM3.js.map +1 -0
- package/dist/{chunk-ET2CNMLD.js → chunk-JN72EPOE.js} +2 -2
- package/dist/{chunk-U62OK7BB.js → chunk-JPKK466T.js} +188 -21
- package/dist/chunk-JPKK466T.js.map +1 -0
- package/dist/{chunk-JCCWJHOP.js → chunk-JYZSRNR7.js} +2 -2
- package/dist/{chunk-7D6HXODY.js → chunk-K7724CH2.js} +2 -2
- package/dist/{chunk-X33MJFD2.js → chunk-KAXCYM66.js} +3 -3
- package/dist/{chunk-7RRUHJPG.js → chunk-KB2G2I6Q.js} +3 -3
- package/dist/{chunk-ZXBTTMGZ.js → chunk-KEF46KL2.js} +5 -5
- package/dist/{chunk-5UZXUTVO.js → chunk-KNA3BXXL.js} +6 -2
- package/dist/chunk-KNA3BXXL.js.map +1 -0
- package/dist/{chunk-UWTDARPF.js → chunk-KTWG7CNY.js} +6 -6
- package/dist/{chunk-XQYTSZW3.js → chunk-L7Z57SID.js} +6 -6
- package/dist/{chunk-JMAG7WZ7.js → chunk-LO4UKPKX.js} +3 -3
- package/dist/{chunk-LDWIPYJ6.js → chunk-LS2FHUML.js} +3 -3
- package/dist/{chunk-GDB4J2H3.js → chunk-MPC7TYTZ.js} +2 -2
- package/dist/{chunk-2GF27PGH.js → chunk-MRPOZBJC.js} +3 -3
- package/dist/{chunk-BR3OOQZQ.js → chunk-MWN6QEI2.js} +2 -2
- package/dist/{chunk-NZGO2GKL.js → chunk-MY5EDR46.js} +4 -4
- package/dist/{chunk-LCMUZDBZ.js → chunk-N3ZOP7KC.js} +3 -3
- package/dist/{chunk-TVW4C7PV.js → chunk-NB3LRY4T.js} +6 -6
- package/dist/{chunk-QJCWK2A7.js → chunk-ND6IQGSZ.js} +2 -2
- package/dist/{chunk-NOB2T2FC.js → chunk-NHLLKEKK.js} +2 -2
- package/dist/{chunk-7GSSHAXC.js → chunk-NLYVH66G.js} +6 -6
- package/dist/chunk-NLYVH66G.js.map +1 -0
- package/dist/{chunk-EJIWBTVM.js → chunk-O6ZNNVSP.js} +2 -2
- package/dist/{chunk-AG46P24C.js → chunk-OB3XMWX5.js} +4 -4
- package/dist/{chunk-NYRB7BKY.js → chunk-OEYZXDQI.js} +6 -6
- package/dist/chunk-OEYZXDQI.js.map +1 -0
- package/dist/{chunk-46QMN7I7.js → chunk-PAZY2ZKP.js} +6 -6
- package/dist/{chunk-EF4JUM55.js → chunk-PX4UMA5Z.js} +2 -2
- package/dist/chunk-QLK3SL7Q.js +242 -0
- package/dist/chunk-QLK3SL7Q.js.map +1 -0
- package/dist/{chunk-GGYDJJBO.js → chunk-QOOBICJF.js} +5 -5
- package/dist/chunk-QOOBICJF.js.map +1 -0
- package/dist/{chunk-NNZFPYYX.js → chunk-R7QY5ZVB.js} +2 -2
- package/dist/{chunk-RO2X2EYM.js → chunk-R7RTXEYG.js} +2 -2
- package/dist/{chunk-3LJPSRAN.js → chunk-RBCQVOVJ.js} +3 -3
- package/dist/{chunk-N4F7ZSSG.js → chunk-RC5DXXWC.js} +2 -2
- package/dist/{chunk-VLAQV4HT.js → chunk-RJYJ7KR7.js} +1636 -611
- package/dist/chunk-RJYJ7KR7.js.map +1 -0
- package/dist/{chunk-5CF2R4NS.js → chunk-RKBLRTNT.js} +2 -2
- package/dist/{chunk-5QZR2RA3.js → chunk-ROBHL3GL.js} +2 -2
- package/dist/{chunk-D5ZNOKR7.js → chunk-S7T2TY65.js} +3 -3
- package/dist/{chunk-C2JCVZWX.js → chunk-SCXURCVT.js} +25 -13
- package/dist/chunk-SCXURCVT.js.map +1 -0
- package/dist/{chunk-3LADWWMA.js → chunk-SJDQ5RSN.js} +3 -3
- package/dist/{chunk-45XVII3J.js → chunk-SMWTZLHE.js} +99 -89
- package/dist/{chunk-45XVII3J.js.map → chunk-SMWTZLHE.js.map} +1 -1
- package/dist/{chunk-XOQGUGJL.js → chunk-SO7SV523.js} +1 -1
- package/dist/{chunk-XOQGUGJL.js.map → chunk-SO7SV523.js.map} +1 -1
- package/dist/{chunk-CHWUICVY.js → chunk-SV4Z2S67.js} +4 -4
- package/dist/{chunk-JHP45LO5.js → chunk-SVXJLDDC.js} +9 -7
- package/dist/{chunk-JHP45LO5.js.map → chunk-SVXJLDDC.js.map} +1 -1
- package/dist/{chunk-SEF4IOFE.js → chunk-SWIKABKI.js} +2 -2
- package/dist/{chunk-JRRQ747T.js → chunk-TBXAY2SS.js} +13 -13
- package/dist/{chunk-J6A3CX5N.js → chunk-TG3FAM2S.js} +33 -8
- package/dist/{chunk-J6A3CX5N.js.map → chunk-TG3FAM2S.js.map} +1 -1
- package/dist/{chunk-XZBXINXZ.js → chunk-TNSCIPBQ.js} +4 -4
- package/dist/{chunk-S37NN23M.js → chunk-TVEONGBU.js} +2 -2
- package/dist/{chunk-5RPMTFB6.js → chunk-TWF35IC6.js} +3 -3
- package/dist/{chunk-BZTJEILZ.js → chunk-U6N5IBVY.js} +2 -2
- package/dist/{chunk-7TUB6JWA.js → chunk-UCKYTA2T.js} +3 -3
- package/dist/{chunk-PPOT6SPR.js → chunk-UNNPNBR2.js} +11 -11
- package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-J2R275FN.js → chunk-VVX5PZFS.js} +4 -4
- package/dist/{chunk-ME35HVDJ.js → chunk-VYCOJKSX.js} +2 -2
- package/dist/{chunk-F5UWQ4LX.js → chunk-W24T5YMW.js} +2 -2
- package/dist/{chunk-HDQUQBPW.js → chunk-W3K3HITK.js} +2 -2
- package/dist/{chunk-GDASG7NC.js → chunk-W4F3C7N7.js} +2 -2
- package/dist/{chunk-LFK623SF.js → chunk-WJHGDE7X.js} +5 -5
- package/dist/{chunk-DP4EBV7C.js → chunk-WMLEPWMO.js} +16 -16
- package/dist/chunk-WMLEPWMO.js.map +1 -0
- package/dist/{chunk-3Q6RD76J.js → chunk-WQZZDN5M.js} +5 -5
- package/dist/{chunk-ZJWDWPX6.js → chunk-X5K5TAQZ.js} +4 -4
- package/dist/{chunk-ZL3XX5LW.js → chunk-XM24CDZX.js} +3 -3
- package/dist/{chunk-JTWZKNUH.js → chunk-XOVKXJEP.js} +3 -3
- package/dist/{chunk-OGTKQ5MJ.js → chunk-XSGUMQQQ.js} +62 -50
- package/dist/chunk-XSGUMQQQ.js.map +1 -0
- package/dist/{chunk-X5YYSAZX.js → chunk-XUE46UYW.js} +3 -3
- package/dist/{chunk-DJORULH3.js → chunk-YRLHEEQT.js} +2 -2
- package/dist/{chunk-TA7UZZMW.js → chunk-Z3O53WZR.js} +2 -2
- package/dist/{chunk-4LG4CPOC.js → chunk-Z6COGHHN.js} +2 -2
- package/dist/{chunk-RE3H6Y2X.js → chunk-ZIW5JVRM.js} +2 -2
- package/dist/{cli-BNtvR-nU.d.ts → cli-DD0P-lu8.d.ts} +6 -6
- package/dist/cli.d.ts +16 -14
- package/dist/cli.js +154 -149
- package/dist/coding/export-okf-codegraph.d.ts +2 -1
- package/dist/coding/export-okf-codegraph.js +37 -37
- package/dist/coding/pre-action-gate.d.ts +2 -1
- package/dist/coding/pre-action-gate.js +4 -3
- package/dist/commitment-ledger.js +3 -2
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +37 -37
- package/dist/compounding/preference-consolidator.d.ts +2 -1
- package/dist/compression-optimizer.d.ts +2 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.js +16 -13
- package/dist/connectors/codex-materialize-runner.d.ts +2 -1
- package/dist/connectors/codex-materialize-runner.js +38 -38
- package/dist/connectors/codex-materialize.d.ts +2 -1
- package/dist/connectors/codex-materialize.js +4 -4
- package/dist/connectors/index.d.ts +2 -1
- package/dist/connectors/index.js +38 -38
- package/dist/consolidation-provenance-check.d.ts +3 -2
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +3 -2
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.d.ts +4 -3
- package/dist/contradiction/index.js +9 -9
- package/dist/converge-config.d.ts +2 -1
- package/dist/convergence-refresh.d.ts +3 -2
- package/dist/convergence-refresh.js +38 -38
- package/dist/conversation-index/backend.d.ts +2 -1
- package/dist/conversation-index/chunker.d.ts +2 -1
- package/dist/conversation-index/faiss-adapter.d.ts +2 -1
- package/dist/conversation-index/indexer.d.ts +2 -1
- package/dist/conversation-index/search.d.ts +2 -1
- package/dist/corpus-watermark.d.ts +2 -1
- package/dist/corpus-watermark.js +38 -38
- package/dist/cross-lingual-recall.d.ts +2 -1
- package/dist/cue-anchors.js +4 -3
- package/dist/dashboard-runtime.js +2 -2
- package/dist/day-summary.d.ts +2 -1
- package/dist/deep-recall-http-glue.d.ts +14 -12
- package/dist/deep-recall-http-glue.js +9 -8
- package/dist/deep-recall-mcp-tools.d.ts +14 -12
- package/dist/deep-recall-policy-llm.d.ts +2 -1
- package/dist/deep-recall-seeds.d.ts +2 -1
- package/dist/deep-recall.js +2 -2
- package/dist/delinearize.d.ts +2 -1
- package/dist/dependency-propagation-config.d.ts +2 -1
- package/dist/{dependency-propagation-delivery-DjpUlhLi.d.ts → dependency-propagation-delivery-CQPCu0o5.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +2 -1
- package/dist/direct-answer.d.ts +2 -1
- package/dist/embedding-fallback.d.ts +2 -1
- package/dist/enrichment/index.d.ts +2 -1
- package/dist/entity-origin-fields.d.ts +2 -1
- package/dist/entity-retrieval.d.ts +3 -2
- package/dist/entity-retrieval.js +36 -36
- package/dist/entity-schema.d.ts +2 -1
- package/dist/episodic-context.d.ts +2 -1
- package/dist/eval-trajectory-contracts.d.ts +2 -1
- package/dist/eval-trajectory-store.d.ts +2 -1
- package/dist/eval-trajectory-store.js +4 -3
- package/dist/eval-trajectory.d.ts +2 -1
- package/dist/eval-trajectory.js +4 -3
- package/dist/evals.js +3 -2
- package/dist/event-order-recall.js +2 -2
- package/dist/explicit-capture.d.ts +12 -10
- package/dist/explicit-capture.js +10 -10
- package/dist/external-wiki-access.d.ts +14 -12
- package/dist/external-wiki-access.js +95 -92
- package/dist/external-wiki-collection-registration.d.ts +2 -1
- package/dist/external-wiki-collection.d.ts +2 -1
- package/dist/external-wiki-mcp-tools.d.ts +14 -12
- package/dist/extraction-error-classification.d.ts +2 -1
- package/dist/extraction-faithfulness.d.ts +2 -1
- package/dist/extraction-judge-telemetry.d.ts +2 -1
- package/dist/extraction-judge-training.d.ts +2 -1
- package/dist/extraction-judge.d.ts +2 -1
- package/dist/extraction-liveness.d.ts +2 -1
- package/dist/extraction-normalization.d.ts +2 -1
- package/dist/extraction-prompt.d.ts +2 -1
- package/dist/extraction-source-grounding-rules.d.ts +2 -1
- package/dist/extraction-source-grounding.d.ts +2 -1
- package/dist/extraction.d.ts +2 -1
- package/dist/extraction.js +43 -43
- package/dist/fallback-llm.d.ts +2 -1
- package/dist/{first-start-migration-KHIMCBIC.js → first-start-migration-RC345GPL.js} +6 -5
- package/dist/{first-start-migration-KHIMCBIC.js.map → first-start-migration-RC345GPL.js.map} +1 -1
- package/dist/{forget-2AE4MDK3.js → forget-SZ2BXDGF.js} +3 -3
- package/dist/{graph-444E-DrF.d.ts → graph-DRkl22KE.d.ts} +10 -12
- package/dist/graph-append-error.d.ts +40 -0
- package/dist/graph-append-error.js +8 -0
- package/dist/graph-dashboard-diff.d.ts +5 -2
- package/dist/graph-dashboard-key.d.ts +5 -2
- package/dist/graph-dashboard-parser.d.ts +5 -2
- package/dist/{graph-edge-decay-DGTBFALQ.js → graph-edge-decay-MKIRZ762.js} +10 -4
- package/dist/graph-edge-decay-MKIRZ762.js.map +1 -0
- package/dist/graph-edge-reinforcement.d.ts +5 -2
- package/dist/graph-jsonl.d.ts +82 -0
- package/dist/graph-jsonl.js +23 -0
- package/dist/graph-jsonl.js.map +1 -0
- package/dist/graph-path-reconstruction.d.ts +5 -2
- package/dist/graph-path-scoring.d.ts +5 -2
- package/dist/graph-snapshot.d.ts +5 -2
- package/dist/graph-snapshot.js +7 -3
- package/dist/graph-write-lock.d.ts +84 -0
- package/dist/graph-write-lock.js +15 -0
- package/dist/graph-write-lock.js.map +1 -0
- package/dist/graph.d.ts +5 -2
- package/dist/graph.js +10 -3
- package/dist/harmonic-construction.js +5 -4
- package/dist/harmonic-retrieval.js +5 -4
- package/dist/importance.d.ts +2 -1
- package/dist/importers/index.d.ts +2 -1
- package/dist/in-flight-reads.d.ts +2 -1
- package/dist/{index-CsUrdMyL.d.ts → index-C9VXenR8.d.ts} +2 -2
- package/dist/index.d.ts +39 -25
- package/dist/index.js +291 -284
- package/dist/intent.d.ts +2 -1
- package/dist/json-store.js +2 -1
- package/dist/lcm/engine.d.ts +2 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +2 -1
- package/dist/lcm/index.js +6 -6
- package/dist/lcm/tools.d.ts +2 -1
- package/dist/lifecycle.d.ts +2 -1
- package/dist/live-connectors-runner.d.ts +2 -1
- package/dist/live-connectors-runner.js +3 -2
- package/dist/local-llm.d.ts +2 -1
- package/dist/local-model-endpoint.d.ts +2 -1
- package/dist/location/index.d.ts +4 -3
- package/dist/location/index.js +39 -39
- package/dist/maintenance/memory-governance.d.ts +2 -1
- package/dist/maintenance/memory-governance.js +36 -36
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +36 -36
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +37 -37
- package/dist/{maintenance-D1GRGLTE.d.ts → maintenance-C14sorKa.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +14 -12
- package/dist/memory-action-policy.d.ts +2 -1
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-controller.d.ts +2 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-projection-mutations.js +3 -3
- package/dist/memory-projection-store.d.ts +2 -1
- package/dist/memory-provenance.d.ts +2 -1
- package/dist/memory-snapshot.d.ts +2 -1
- package/dist/memory-subject-cli.d.ts +14 -12
- package/dist/memory-subject.d.ts +14 -12
- package/dist/memory-subject.js +5 -5
- package/dist/memory-worth-outcomes.d.ts +3 -2
- package/dist/models-json.d.ts +2 -1
- package/dist/namespaces/migrate.d.ts +4 -3
- package/dist/namespaces/migrate.js +37 -37
- package/dist/namespaces/principal.d.ts +2 -1
- package/dist/namespaces/search.d.ts +2 -1
- package/dist/namespaces/search.js +11 -11
- package/dist/namespaces/storage.d.ts +4 -3
- package/dist/namespaces/storage.js +36 -36
- package/dist/native-knowledge.d.ts +2 -1
- package/dist/objective-state-writers.js +4 -3
- package/dist/objective-state.js +3 -2
- package/dist/offline-sync-file-io.js +4 -3
- package/dist/offline-sync-impression-drain.d.ts +2 -1
- package/dist/offline-sync-impression-drain.js +7 -7
- package/dist/offline-sync.js +5 -4
- package/dist/operator-doctor-corpus.d.ts +2 -1
- package/dist/operator-doctor-corpus.js +39 -39
- package/dist/operator-doctor-replica.d.ts +2 -1
- package/dist/operator-toolkit.d.ts +6 -4
- package/dist/operator-toolkit.js +61 -58
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +46 -46
- package/dist/{orchestrator-DeqaPGT5.d.ts → orchestrator-DgyvFfPR.d.ts} +9 -9
- package/dist/orchestrator.d.ts +12 -10
- package/dist/orchestrator.js +201 -196
- package/dist/page-versioning.d.ts +73 -4
- package/dist/page-versioning.js +11 -3
- package/dist/patterns-cli.d.ts +2 -1
- package/dist/{pipeline-umUzU0D1.d.ts → pipeline-DRUwHb1X.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +2 -1
- package/dist/proactive-contention.d.ts +2 -1
- package/dist/provenance.d.ts +2 -1
- package/dist/{public-http-Bevrjll9.d.ts → public-http-C4i8Opxc.d.ts} +1 -1
- package/dist/{purge-OP6BEDFY.js → purge-TZKRE6ZQ.js} +5 -5
- package/dist/purge-TZKRE6ZQ.js.map +1 -0
- package/dist/{qmd-BasT78PP.d.ts → qmd-BVWlg1YS.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +3 -2
- package/dist/qmd-recall-cache.d.ts +2 -1
- package/dist/qmd.d.ts +3 -2
- package/dist/qmd.js +4 -4
- package/dist/recall-concurrency-config.d.ts +2 -1
- package/dist/recall-disclosure-escalation.d.ts +2 -1
- package/dist/recall-explain-renderer.d.ts +2 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +2 -1
- package/dist/recall-navigate-access.d.ts +2 -1
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.d.ts +2 -1
- package/dist/recall-navigate-disclosure.js +1 -1
- package/dist/recall-navigate.d.ts +2 -1
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-planner-llm.d.ts +2 -1
- package/dist/recall-state.d.ts +2 -1
- package/dist/recall-state.js +3 -3
- package/dist/recall-tag-filter.d.ts +2 -1
- package/dist/recall-timings.d.ts +2 -1
- package/dist/recall-xray-cli.d.ts +2 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +2 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +2 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +2 -1
- package/dist/reconcile/manifest.d.ts +2 -1
- package/dist/reconcile/manifest.js +7 -7
- package/dist/reconcile/plan.d.ts +2 -1
- package/dist/replay/normalizers/chatgpt.d.ts +2 -1
- package/dist/replay/normalizers/claude.d.ts +2 -1
- package/dist/replay/normalizers/openclaw.d.ts +2 -1
- package/dist/replay/normalizers/shared.d.ts +2 -1
- package/dist/replay/runner.d.ts +2 -1
- package/dist/replay/types.d.ts +2 -1
- package/dist/replica-divergence.d.ts +2 -1
- package/dist/replica-peers-config.d.ts +2 -1
- package/dist/{resolution-4DLI3IOR.js → resolution-VKATP2HT.js} +10 -10
- package/dist/resolution-VKATP2HT.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +2 -1
- package/dist/resume-bundles.js +21 -18
- package/dist/retrieval-agents.d.ts +3 -2
- package/dist/retrieval-tiers.d.ts +2 -1
- package/dist/routing/engine.d.ts +2 -1
- package/dist/routing/store.d.ts +2 -1
- package/dist/salvage-envelope.d.ts +2 -1
- package/dist/salvage-envelope.js +7 -7
- package/dist/{scope-profiles-DXYzyOXW.d.ts → scope-profiles-Vl00B1KU.d.ts} +1 -1
- package/dist/search/document-scanner.js +3 -3
- package/dist/search/embed-helper.d.ts +2 -1
- package/dist/search/factory.d.ts +2 -1
- package/dist/search/factory.js +10 -10
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.js +16 -16
- package/dist/search/lancedb-backend.d.ts +2 -1
- package/dist/search/lancedb-backend.js +4 -4
- package/dist/search/meilisearch-backend.d.ts +2 -1
- package/dist/search/meilisearch-backend.js +4 -4
- package/dist/search/noop-backend.d.ts +2 -1
- package/dist/search/orama-backend.d.ts +2 -1
- package/dist/search/orama-backend.js +4 -4
- package/dist/search/port.d.ts +2 -1
- package/dist/search/remote-backend.d.ts +2 -1
- package/dist/secure-store/index.js +3 -3
- package/dist/{semantic-consolidation-CqDeaY0U.d.ts → semantic-consolidation-BC9-GFuT.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +3 -2
- package/dist/semantic-consolidation.js +39 -39
- package/dist/semantic-merge-config.d.ts +17 -0
- package/dist/semantic-merge-config.js +1 -0
- package/dist/semantic-merge-config.js.map +1 -0
- package/dist/semantic-rule-promotion.js +36 -36
- package/dist/semantic-rule-verifier.d.ts +2 -1
- package/dist/semantic-rule-verifier.js +36 -36
- package/dist/{service-BKD-DVYZ.d.ts → service-BOy6dHfc.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +2 -1
- package/dist/session-observer-state.d.ts +2 -1
- package/dist/shared-context/manager.d.ts +2 -1
- package/dist/signal.d.ts +2 -1
- package/dist/source-agent-qualifier.d.ts +2 -1
- package/dist/source-agent-qualifier.js +42 -42
- package/dist/source-attribution.d.ts +18 -6
- package/dist/source-attribution.js +3 -1
- package/dist/standup/build.js +36 -36
- package/dist/{storage-BcFd1lN_.d.ts → storage-BLJRnFi6.d.ts} +15 -8
- package/dist/storage.d.ts +3 -2
- package/dist/storage.js +35 -35
- package/dist/subject-config.d.ts +2 -1
- package/dist/subject-config.js +6 -6
- package/dist/summarizer.d.ts +2 -1
- package/dist/summary-snapshot.d.ts +2 -1
- package/dist/support-passport/index.d.ts +17 -15
- package/dist/support-passport/index.js +97 -94
- package/dist/temporal-supersession.d.ts +3 -2
- package/dist/temporal-timeline-recall.d.ts +2 -1
- package/dist/temporal-validity.d.ts +2 -1
- package/dist/threading.d.ts +2 -1
- package/dist/tier-migration.d.ts +3 -2
- package/dist/tier-routing.d.ts +2 -1
- package/dist/{tier-stats-2TOW3QNL.js → tier-stats-KA6OZX2C.js} +6 -5
- package/dist/{tier-stats-2TOW3QNL.js.map → tier-stats-KA6OZX2C.js.map} +1 -1
- package/dist/topics.d.ts +2 -1
- package/dist/transcript.d.ts +2 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +6 -6
- package/dist/transfer/export-okf.d.ts +2 -1
- package/dist/transfer/export-okf.js +37 -37
- package/dist/trust-score-stage.d.ts +2 -1
- package/dist/trust-score.d.ts +2 -1
- package/dist/trust-zones.js +3 -2
- package/dist/{types-BRg3tMyp.d.ts → types-YY-eKKU7.d.ts} +3 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/dist/utility-learner.js +4 -3
- package/dist/utility-runtime.d.ts +2 -1
- package/dist/utility-runtime.js +5 -4
- package/dist/utility-telemetry.js +3 -2
- package/dist/verified-recall.js +36 -36
- package/dist/who-knows-cli.d.ts +14 -12
- package/dist/who-knows-cli.js +37 -37
- package/dist/who-knows.d.ts +14 -12
- package/dist/who-knows.js +36 -36
- package/dist/work/board.js +3 -3
- package/dist/work/storage.js +2 -2
- package/dist/work-product-ledger.js +3 -2
- package/dist/write-envelope.d.ts +2 -1
- package/dist/write-envelope.js +6 -6
- package/package.json +2 -2
- package/src/abstraction-nodes.ts +1 -4
- package/src/access-http-briefing.ts +35 -0
- package/src/access-http.test.ts +76 -0
- package/src/access-http.ts +20 -23
- package/src/access-surface-catalog.test.ts +9 -0
- package/src/access-surface-catalog.ts +1 -0
- package/src/binary-lifecycle/backend.ts +2 -1
- package/src/config.ts +2 -0
- package/src/connectors/live/github.ts +10 -17
- package/src/connectors/live/gmail.ts +8 -19
- package/src/connectors/live/google-drive.ts +6 -13
- package/src/connectors/live/notion.ts +11 -21
- package/src/cue-anchors.ts +1 -6
- package/src/dedup/connector-scope.ts +39 -0
- package/src/dedup/merge-content.test.ts +21 -0
- package/src/dedup/merge-content.ts +21 -7
- package/src/dedup/merge-judge.ts +146 -0
- package/src/dedup/merge.test.ts +3542 -0
- package/src/dedup/merge.ts +384 -0
- package/src/dedup/novelty-gate.ts +12 -10
- package/src/dedup/semantic.ts +7 -9
- package/src/graph-append-error.ts +28 -0
- package/src/graph-jsonl.ts +267 -0
- package/src/graph-write-lock.test.ts +228 -0
- package/src/graph-write-lock.ts +132 -0
- package/src/graph.ts +49 -45
- package/src/harmonic-construction.test.ts +329 -0
- package/src/json-store.ts +17 -20
- package/src/live-connectors-runner.ts +2 -1
- package/src/location/store.ts +1 -4
- package/src/maintenance/graph-edge-decay.ts +24 -13
- package/src/maintenance/purge.ts +2 -5
- package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +3 -6
- package/src/maintenance/rebuild-memory-projection.ts +2 -5
- package/src/namespaces/catalog.ts +1 -9
- package/src/offline-sync-file-io.test.ts +39 -0
- package/src/offline-sync-file-io.ts +3 -7
- package/src/orchestration/contradiction-localization.integration.test.ts +35 -0
- package/src/orchestration/extraction-anchor-snapshot.ts +6 -1
- package/src/orchestration/extraction-persist-deps.ts +2 -1
- package/src/orchestration/extraction-persist-profile-promotion.test.ts +456 -0
- package/src/orchestration/extraction-persist-promotion.test.ts +534 -0
- package/src/orchestration/extraction-persist-promotion.ts +387 -1
- package/src/orchestration/extraction-persist.ts +95 -94
- package/src/orchestration/harmonic-construction-persist.test.ts +69 -0
- package/src/orchestration/harmonic-construction-persist.ts +55 -0
- package/src/orchestration/persistence-index.ts +35 -7
- package/src/orchestration/semantic-merge-commit-effects.ts +354 -0
- package/src/orchestration/semantic-merge-persist.ts +1095 -0
- package/src/orchestration/semantic-merge-promotion-payload.ts +161 -0
- package/src/orchestrator.ts +2 -2
- package/src/page-versioning.ts +396 -22
- package/src/procedural/procedure-miner.ts +1 -9
- package/src/search/document-scanner.ts +3 -6
- package/src/semantic-merge-config.ts +16 -0
- package/src/semantic-rule-promotion.ts +1 -4
- package/src/source-attribution-roundtrip.test.ts +21 -0
- package/src/source-attribution.ts +57 -17
- package/src/storage-contract/versioning.test.ts +500 -1
- package/src/storage.ts +30 -30
- package/src/testing/subjects/graph-edge-decay.test.ts +163 -0
- package/src/testing/subjects/semantic-merge-lifecycle.test.ts +1175 -0
- package/src/types.ts +2 -0
- package/src/utils/errno.test.ts +31 -0
- package/src/utils/errno.ts +5 -0
- package/src/wearables/index.ts +1 -0
- package/src/wearables/registry.ts +23 -0
- package/dist/chunk-5UZXUTVO.js.map +0 -1
- package/dist/chunk-7GSSHAXC.js.map +0 -1
- package/dist/chunk-ACPCA4NO.js.map +0 -1
- package/dist/chunk-C2JCVZWX.js.map +0 -1
- package/dist/chunk-DDQQY2E3.js.map +0 -1
- package/dist/chunk-DJUKBGAD.js.map +0 -1
- package/dist/chunk-DK6GMO6D.js.map +0 -1
- package/dist/chunk-DP4EBV7C.js.map +0 -1
- package/dist/chunk-FCATYKQA.js.map +0 -1
- package/dist/chunk-GGYDJJBO.js.map +0 -1
- package/dist/chunk-HTIIXNJQ.js.map +0 -1
- package/dist/chunk-KK66P5GQ.js.map +0 -1
- package/dist/chunk-NQFCLAYT.js.map +0 -1
- package/dist/chunk-NYRB7BKY.js.map +0 -1
- package/dist/chunk-OGTKQ5MJ.js.map +0 -1
- package/dist/chunk-OLT3YTDH.js.map +0 -1
- package/dist/chunk-P77QX3ID.js.map +0 -1
- package/dist/chunk-U62OK7BB.js.map +0 -1
- package/dist/chunk-UR6PBX2J.js.map +0 -1
- package/dist/chunk-VLAQV4HT.js.map +0 -1
- package/dist/chunk-W7IGLX4G.js.map +0 -1
- package/dist/purge-OP6BEDFY.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → access-http-briefing.js.map} +0 -0
- /package/dist/{auto-sync-GRUJFD2F.js.map → auto-sync-WNGG2GC2.js.map} +0 -0
- /package/dist/{graph-edge-decay-DGTBFALQ.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
- /package/dist/{capsule-merge-SEHERWWP.js.map → capsule-merge-IPG4IOFP.js.map} +0 -0
- /package/dist/{chunk-KTVSPFCQ.js.map → chunk-22FVR2KE.js.map} +0 -0
- /package/dist/{chunk-7Y5V3LAP.js.map → chunk-27QVNSQ3.js.map} +0 -0
- /package/dist/{chunk-R7LY4YKF.js.map → chunk-2EKJDQZB.js.map} +0 -0
- /package/dist/{chunk-HOUST5UX.js.map → chunk-2ITE4C2Z.js.map} +0 -0
- /package/dist/{chunk-JOYC4RYC.js.map → chunk-2JVJ7UHC.js.map} +0 -0
- /package/dist/{chunk-X2NFFBTO.js.map → chunk-2L5FSNPC.js.map} +0 -0
- /package/dist/{chunk-DUAJKRR2.js.map → chunk-2SGLMP2E.js.map} +0 -0
- /package/dist/{chunk-6FUMA6AA.js.map → chunk-2Z4GS5E6.js.map} +0 -0
- /package/dist/{chunk-G6MXN2G5.js.map → chunk-37KUQPX4.js.map} +0 -0
- /package/dist/{chunk-WKAXBXVA.js.map → chunk-3QQTXYZ6.js.map} +0 -0
- /package/dist/{chunk-4ZWCQJNM.js.map → chunk-46WM6JX2.js.map} +0 -0
- /package/dist/{chunk-CASWJ2HM.js.map → chunk-46ZPIGWI.js.map} +0 -0
- /package/dist/{chunk-MCA2X4WH.js.map → chunk-4IHBN6WU.js.map} +0 -0
- /package/dist/{chunk-FB7LAJQM.js.map → chunk-4TKJGOCJ.js.map} +0 -0
- /package/dist/{chunk-H7BZBSP6.js.map → chunk-52II7PB6.js.map} +0 -0
- /package/dist/{chunk-N4Y5T6VD.js.map → chunk-54WHLA65.js.map} +0 -0
- /package/dist/{chunk-YVLENSNS.js.map → chunk-5ATKSPEQ.js.map} +0 -0
- /package/dist/{chunk-ZVZHG7AI.js.map → chunk-5UBH37SL.js.map} +0 -0
- /package/dist/{chunk-N3WZU76A.js.map → chunk-66OJSCI6.js.map} +0 -0
- /package/dist/{chunk-D35XLYQ7.js.map → chunk-6CVNSDCZ.js.map} +0 -0
- /package/dist/{chunk-KA2HZCMG.js.map → chunk-6NXSYYGP.js.map} +0 -0
- /package/dist/{chunk-2HIJHXB3.js.map → chunk-6WHJ2EAB.js.map} +0 -0
- /package/dist/{chunk-ZZM476NV.js.map → chunk-6XL73HQ4.js.map} +0 -0
- /package/dist/{chunk-EJ5RKUXW.js.map → chunk-AQ7SYDVO.js.map} +0 -0
- /package/dist/{chunk-2Z3DG5CQ.js.map → chunk-B3O3IRZN.js.map} +0 -0
- /package/dist/{chunk-RACZB5HT.js.map → chunk-BD7JTBYP.js.map} +0 -0
- /package/dist/{chunk-I762GW7V.js.map → chunk-BLJWYCNO.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-GCASGYIO.js.map → chunk-C7HJ3NEI.js.map} +0 -0
- /package/dist/{chunk-C24UZSFW.js.map → chunk-CEH2AFXG.js.map} +0 -0
- /package/dist/{chunk-WVGXCBOC.js.map → chunk-D5F7TKMH.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-2OXIPF3A.js.map → chunk-DZD3WGCD.js.map} +0 -0
- /package/dist/{chunk-UMEOXLIZ.js.map → chunk-E2P7TZTF.js.map} +0 -0
- /package/dist/{chunk-6FC3IZ26.js.map → chunk-EBA5DA77.js.map} +0 -0
- /package/dist/{chunk-N7JK2RKG.js.map → chunk-EOQ6FSQP.js.map} +0 -0
- /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
- /package/dist/{chunk-XDMI5VKE.js.map → chunk-FVOP3NT7.js.map} +0 -0
- /package/dist/{chunk-NRLELHAY.js.map → chunk-G7NYVKD6.js.map} +0 -0
- /package/dist/{chunk-B3W7GWQB.js.map → chunk-GHTSNGBZ.js.map} +0 -0
- /package/dist/{chunk-LUDBXTBJ.js.map → chunk-H272ZPQ3.js.map} +0 -0
- /package/dist/{chunk-SN4JXNLL.js.map → chunk-H3TKENU4.js.map} +0 -0
- /package/dist/{chunk-4HYNMLT6.js.map → chunk-H4SEGIZY.js.map} +0 -0
- /package/dist/{chunk-ACZN5ZXD.js.map → chunk-H54VWRPS.js.map} +0 -0
- /package/dist/{chunk-HTP6XRUI.js.map → chunk-HM7RHKS4.js.map} +0 -0
- /package/dist/{chunk-Z3SQEEB6.js.map → chunk-HWLIMQE2.js.map} +0 -0
- /package/dist/{chunk-2QSZNTDO.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-ET2CNMLD.js.map → chunk-JN72EPOE.js.map} +0 -0
- /package/dist/{chunk-JCCWJHOP.js.map → chunk-JYZSRNR7.js.map} +0 -0
- /package/dist/{chunk-7D6HXODY.js.map → chunk-K7724CH2.js.map} +0 -0
- /package/dist/{chunk-X33MJFD2.js.map → chunk-KAXCYM66.js.map} +0 -0
- /package/dist/{chunk-7RRUHJPG.js.map → chunk-KB2G2I6Q.js.map} +0 -0
- /package/dist/{chunk-ZXBTTMGZ.js.map → chunk-KEF46KL2.js.map} +0 -0
- /package/dist/{chunk-UWTDARPF.js.map → chunk-KTWG7CNY.js.map} +0 -0
- /package/dist/{chunk-XQYTSZW3.js.map → chunk-L7Z57SID.js.map} +0 -0
- /package/dist/{chunk-JMAG7WZ7.js.map → chunk-LO4UKPKX.js.map} +0 -0
- /package/dist/{chunk-LDWIPYJ6.js.map → chunk-LS2FHUML.js.map} +0 -0
- /package/dist/{chunk-GDB4J2H3.js.map → chunk-MPC7TYTZ.js.map} +0 -0
- /package/dist/{chunk-2GF27PGH.js.map → chunk-MRPOZBJC.js.map} +0 -0
- /package/dist/{chunk-BR3OOQZQ.js.map → chunk-MWN6QEI2.js.map} +0 -0
- /package/dist/{chunk-NZGO2GKL.js.map → chunk-MY5EDR46.js.map} +0 -0
- /package/dist/{chunk-LCMUZDBZ.js.map → chunk-N3ZOP7KC.js.map} +0 -0
- /package/dist/{chunk-TVW4C7PV.js.map → chunk-NB3LRY4T.js.map} +0 -0
- /package/dist/{chunk-QJCWK2A7.js.map → chunk-ND6IQGSZ.js.map} +0 -0
- /package/dist/{chunk-NOB2T2FC.js.map → chunk-NHLLKEKK.js.map} +0 -0
- /package/dist/{chunk-EJIWBTVM.js.map → chunk-O6ZNNVSP.js.map} +0 -0
- /package/dist/{chunk-AG46P24C.js.map → chunk-OB3XMWX5.js.map} +0 -0
- /package/dist/{chunk-46QMN7I7.js.map → chunk-PAZY2ZKP.js.map} +0 -0
- /package/dist/{chunk-EF4JUM55.js.map → chunk-PX4UMA5Z.js.map} +0 -0
- /package/dist/{chunk-NNZFPYYX.js.map → chunk-R7QY5ZVB.js.map} +0 -0
- /package/dist/{chunk-RO2X2EYM.js.map → chunk-R7RTXEYG.js.map} +0 -0
- /package/dist/{chunk-3LJPSRAN.js.map → chunk-RBCQVOVJ.js.map} +0 -0
- /package/dist/{chunk-N4F7ZSSG.js.map → chunk-RC5DXXWC.js.map} +0 -0
- /package/dist/{chunk-5CF2R4NS.js.map → chunk-RKBLRTNT.js.map} +0 -0
- /package/dist/{chunk-5QZR2RA3.js.map → chunk-ROBHL3GL.js.map} +0 -0
- /package/dist/{chunk-D5ZNOKR7.js.map → chunk-S7T2TY65.js.map} +0 -0
- /package/dist/{chunk-3LADWWMA.js.map → chunk-SJDQ5RSN.js.map} +0 -0
- /package/dist/{chunk-CHWUICVY.js.map → chunk-SV4Z2S67.js.map} +0 -0
- /package/dist/{chunk-SEF4IOFE.js.map → chunk-SWIKABKI.js.map} +0 -0
- /package/dist/{chunk-JRRQ747T.js.map → chunk-TBXAY2SS.js.map} +0 -0
- /package/dist/{chunk-XZBXINXZ.js.map → chunk-TNSCIPBQ.js.map} +0 -0
- /package/dist/{chunk-S37NN23M.js.map → chunk-TVEONGBU.js.map} +0 -0
- /package/dist/{chunk-5RPMTFB6.js.map → chunk-TWF35IC6.js.map} +0 -0
- /package/dist/{chunk-BZTJEILZ.js.map → chunk-U6N5IBVY.js.map} +0 -0
- /package/dist/{chunk-7TUB6JWA.js.map → chunk-UCKYTA2T.js.map} +0 -0
- /package/dist/{chunk-PPOT6SPR.js.map → chunk-UNNPNBR2.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-J2R275FN.js.map → chunk-VVX5PZFS.js.map} +0 -0
- /package/dist/{chunk-ME35HVDJ.js.map → chunk-VYCOJKSX.js.map} +0 -0
- /package/dist/{chunk-F5UWQ4LX.js.map → chunk-W24T5YMW.js.map} +0 -0
- /package/dist/{chunk-HDQUQBPW.js.map → chunk-W3K3HITK.js.map} +0 -0
- /package/dist/{chunk-GDASG7NC.js.map → chunk-W4F3C7N7.js.map} +0 -0
- /package/dist/{chunk-LFK623SF.js.map → chunk-WJHGDE7X.js.map} +0 -0
- /package/dist/{chunk-3Q6RD76J.js.map → chunk-WQZZDN5M.js.map} +0 -0
- /package/dist/{chunk-ZJWDWPX6.js.map → chunk-X5K5TAQZ.js.map} +0 -0
- /package/dist/{chunk-ZL3XX5LW.js.map → chunk-XM24CDZX.js.map} +0 -0
- /package/dist/{chunk-JTWZKNUH.js.map → chunk-XOVKXJEP.js.map} +0 -0
- /package/dist/{chunk-X5YYSAZX.js.map → chunk-XUE46UYW.js.map} +0 -0
- /package/dist/{chunk-DJORULH3.js.map → chunk-YRLHEEQT.js.map} +0 -0
- /package/dist/{chunk-TA7UZZMW.js.map → chunk-Z3O53WZR.js.map} +0 -0
- /package/dist/{chunk-4LG4CPOC.js.map → chunk-Z6COGHHN.js.map} +0 -0
- /package/dist/{chunk-RE3H6Y2X.js.map → chunk-ZIW5JVRM.js.map} +0 -0
- /package/dist/{forget-2AE4MDK3.js.map → forget-SZ2BXDGF.js.map} +0 -0
- /package/dist/{resolution-4DLI3IOR.js.map → graph-append-error.js.map} +0 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph JSONL rewrite primitives (sibling of graph.ts, kept out so graph.ts
|
|
3
|
+
* stays under the 1200-LOC new-work cap of issue #1995).
|
|
4
|
+
*
|
|
5
|
+
* `appendEdge` in graph.ts is append-only by design. These helpers are the
|
|
6
|
+
* REPLACE path: callers that re-write an existing node's edges (the
|
|
7
|
+
* judge-merged target of issue #2330) must first drop the node's prior
|
|
8
|
+
* generated edges or every re-write duplicates them.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { mkdir, rename, writeFile } from "node:fs/promises";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import { log } from "./logger.js";
|
|
14
|
+
import { graphFilePath, readEdgesStrict, withGraphWriteLock, type GraphEdge, type GraphType } from "./graph.js";
|
|
15
|
+
import {
|
|
16
|
+
assertGraphLockHeld,
|
|
17
|
+
yieldForLockHeartbeat,
|
|
18
|
+
type GraphWriteLockSection,
|
|
19
|
+
} from "./graph-write-lock.js";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Write a graph JSONL file atomically using temp+rename (gotcha #54: never
|
|
23
|
+
* delete-then-rename; rename is atomic on the same filesystem). Shared by
|
|
24
|
+
* the edge-decay rewrite and node-edge replacement so every JSONL rewrite
|
|
25
|
+
* path serializes on the same lock and the same atomic-write discipline.
|
|
26
|
+
*/
|
|
27
|
+
/** Serialize batch size at which body building yields to the event loop
|
|
28
|
+
* (round N+19 A): one `map+join` over a large corpus blocks the loop past
|
|
29
|
+
* the lock's heartbeat window. */
|
|
30
|
+
const EDGE_SERIALIZE_YIELD_BATCH = 5_000;
|
|
31
|
+
|
|
32
|
+
export async function writeGraphJsonlAtomic(
|
|
33
|
+
filePath: string,
|
|
34
|
+
edges: GraphEdge[],
|
|
35
|
+
lock: GraphWriteLockSection,
|
|
36
|
+
): Promise<void> {
|
|
37
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
38
|
+
// Chunked with event-loop yields: the caller holds the graph write lock,
|
|
39
|
+
// and its mtime heartbeat is a timer that cannot fire while a single
|
|
40
|
+
// synchronous stringify pass over a multi-hundred-thousand-row corpus
|
|
41
|
+
// blocks the loop (round N+19 A).
|
|
42
|
+
let body = "";
|
|
43
|
+
for (let i = 0; i < edges.length; i += EDGE_SERIALIZE_YIELD_BATCH) {
|
|
44
|
+
if (i > 0) await yieldForLockHeartbeat();
|
|
45
|
+
const end = Math.min(i + EDGE_SERIALIZE_YIELD_BATCH, edges.length);
|
|
46
|
+
for (let j = i; j < end; j += 1) {
|
|
47
|
+
body += `${JSON.stringify(edges[j])}\n`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const tempPath = `${filePath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
51
|
+
await writeFile(tempPath, body, "utf-8");
|
|
52
|
+
// Round N+20 (A): the callers' pre-build guards cannot cover the build
|
|
53
|
+
// itself — a section paused past the stale window between the caller's
|
|
54
|
+
// check and this rename resumes to publish over the peer that broke the
|
|
55
|
+
// lock and wrote its own newer graph. Revalidate ownership immediately
|
|
56
|
+
// before the destructive rename; a lost lock aborts and leaves the peer's
|
|
57
|
+
// file untouched (the staged temp is orphaned, same as a rename failure).
|
|
58
|
+
await assertGraphLockHeld(filePath, lock);
|
|
59
|
+
await rename(tempPath, filePath);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Which edges a node's OWN write generates, per graph type (round N+7 G):
|
|
64
|
+
* - entity: the node is the `from` side (node → entity siblings);
|
|
65
|
+
* - time/causal: the node is the `to` side (predecessor → node) — the
|
|
66
|
+
* write links BACK to its predecessor, so the inbound edge is the one
|
|
67
|
+
* this node's write created. The node's outbound time/causal edges
|
|
68
|
+
* (node → later nodes) belong to those LATER nodes' writes and are never
|
|
69
|
+
* touched here.
|
|
70
|
+
*/
|
|
71
|
+
function isNodeGeneratedEdge(edge: GraphEdge, type: GraphType, memoryPath: string): boolean {
|
|
72
|
+
return type === "entity" ? edge.from === memoryPath : edge.to === memoryPath;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** The edges one removal dropped from one graph file, kept for restoration. */
|
|
76
|
+
export interface RemovedNodeEdges {
|
|
77
|
+
type: GraphType;
|
|
78
|
+
filePath: string;
|
|
79
|
+
removed: GraphEdge[];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Remove an existing node's prior generated edges across the given graph
|
|
84
|
+
* types so a RE-write of the same node (a judge-merged memory, issue #2330)
|
|
85
|
+
* REPLACES them instead of re-appending them into the append-only JSONL —
|
|
86
|
+
* duplicates `spreadingActivation` sums into candidate scores and that grow
|
|
87
|
+
* without bound. One shared routine covers every enabled type; there is no
|
|
88
|
+
* per-type copy. Read and rewrite run under the same per-file write lock as
|
|
89
|
+
* `appendEdge` so a concurrent append cannot be dropped (issue #729). The
|
|
90
|
+
* removed edges are RETURNED so the caller can restore them when the
|
|
91
|
+
* replacement build fails (round N+7 E).
|
|
92
|
+
*/
|
|
93
|
+
export async function removeNodeEdgesForRewrite(
|
|
94
|
+
memoryDir: string,
|
|
95
|
+
memoryPath: string,
|
|
96
|
+
types: readonly GraphType[],
|
|
97
|
+
): Promise<RemovedNodeEdges[]> {
|
|
98
|
+
const results: RemovedNodeEdges[] = [];
|
|
99
|
+
for (const type of types) {
|
|
100
|
+
const filePath = graphFilePath(memoryDir, type);
|
|
101
|
+
let removed: GraphEdge[];
|
|
102
|
+
try {
|
|
103
|
+
removed = await withGraphWriteLock(filePath, async (lock) => {
|
|
104
|
+
const edges = await readEdgesStrict(memoryDir, type);
|
|
105
|
+
const removedEdges = edges.filter((edge) => isNodeGeneratedEdge(edge, type, memoryPath));
|
|
106
|
+
if (removedEdges.length === 0) return [];
|
|
107
|
+
// Round N+19 A: a peer may have stale-broken this lock while a large
|
|
108
|
+
// parse blocked the loop — revalidate ownership before publishing the
|
|
109
|
+
// replacement; a lost lock aborts (the catch below restores any
|
|
110
|
+
// earlier committed types, then rethrows).
|
|
111
|
+
await assertGraphLockHeld(filePath, lock);
|
|
112
|
+
await writeGraphJsonlAtomic(
|
|
113
|
+
filePath,
|
|
114
|
+
edges.filter((edge) => !isNodeGeneratedEdge(edge, type, memoryPath)),
|
|
115
|
+
lock,
|
|
116
|
+
);
|
|
117
|
+
return removedEdges;
|
|
118
|
+
});
|
|
119
|
+
} catch (err) {
|
|
120
|
+
// A partial pass (type 1 committed, type 2 failed) must not leave the
|
|
121
|
+
// committed removal stranded: undo what already landed, then surface.
|
|
122
|
+
for (const done of results) {
|
|
123
|
+
await restoreRemovedNodeEdges(memoryDir, done).catch(() => undefined);
|
|
124
|
+
}
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
if (removed.length > 0) results.push({ type, filePath, removed });
|
|
128
|
+
}
|
|
129
|
+
return results;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Restore edges a {@link removeNodeEdgesForRewrite} pass dropped, after the
|
|
134
|
+
* replacement build FAILED (round N+7 E): failure must leave either the old
|
|
135
|
+
* or the new complete set, never none. Appends the removed edges back under
|
|
136
|
+
* the same per-file lock, deduped on the exact JSON row so a retry that
|
|
137
|
+
* partially succeeded cannot double them.
|
|
138
|
+
*/
|
|
139
|
+
export async function restoreRemovedNodeEdges(
|
|
140
|
+
memoryDir: string,
|
|
141
|
+
removed: RemovedNodeEdges,
|
|
142
|
+
): Promise<number> {
|
|
143
|
+
if (removed.removed.length === 0) return 0;
|
|
144
|
+
return withGraphWriteLock(removed.filePath, async (lock) => {
|
|
145
|
+
const current = await readEdgesStrict(memoryDir, removed.type);
|
|
146
|
+
const present = new Set(current.map((edge) => JSON.stringify(edge)));
|
|
147
|
+
const toRestore = removed.removed.filter((edge) => !present.has(JSON.stringify(edge)));
|
|
148
|
+
if (toRestore.length === 0) return 0;
|
|
149
|
+
// Round N+19 A: revalidate ownership before restoring over the file —
|
|
150
|
+
// a peer that broke the lock owns the file now, and restoring our older
|
|
151
|
+
// snapshot over its write would clobber it. The throw leaves the current
|
|
152
|
+
// (peer-owned) file intact; callers log the skipped restore.
|
|
153
|
+
await assertGraphLockHeld(removed.filePath, lock);
|
|
154
|
+
await writeGraphJsonlAtomic(removed.filePath, [...current, ...toRestore], lock);
|
|
155
|
+
return toRestore.length;
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Round N+10 (C) + N+14 companion to {@link removeNodeEdgesForRewrite}: the
|
|
161
|
+
* replacement build FAILED or was superseded, possibly after appending SOME
|
|
162
|
+
* of the node's new edges. Two duties, both scoped to what THIS writer did:
|
|
163
|
+
*
|
|
164
|
+
* 1. Remove the rows the failed build actually appended. When `appended` is
|
|
165
|
+
* provided the removal is surgical — by exact JSON row identity, per
|
|
166
|
+
* file, under the same per-file lock — so rows a NEWER writer appended
|
|
167
|
+
* after this writer's removal (never in this writer's snapshot) survive.
|
|
168
|
+
* Rows a newer writer already swept are simply absent and the removal is
|
|
169
|
+
* a no-op. Since round N+16 (A) a THROWING build carries its partial row
|
|
170
|
+
* set on `GraphEdgeAppendError`, so the surgical path holds on the throw
|
|
171
|
+
* too; only a build that neither returns rows nor wraps its failure
|
|
172
|
+
* falls back to the node-wide sweep of
|
|
173
|
+
* {@link removeNodeEdgesForRewrite}: identical outcome when no newer
|
|
174
|
+
* writer interleaved.
|
|
175
|
+
* 2. Restore the snapshot the original removal dropped — but only for graph
|
|
176
|
+
* types whose file holds NO unexplained node rows after step 1. A type
|
|
177
|
+
* that still has node rows this writer cannot account for is owned by the
|
|
178
|
+
* newer writer's completed rebuild; restoring the older snapshot over it
|
|
179
|
+
* left the memory holding B's body while graph recall reflected the
|
|
180
|
+
* pre-A state (the N+14 finding). Types swept clean restore verbatim
|
|
181
|
+
* (N+7 E: failure leaves the old or the new complete set, never none).
|
|
182
|
+
*/
|
|
183
|
+
export async function rollbackNodeEdgeRewrite(
|
|
184
|
+
memoryDir: string,
|
|
185
|
+
memoryPath: string,
|
|
186
|
+
types: readonly GraphType[],
|
|
187
|
+
removed: RemovedNodeEdges[],
|
|
188
|
+
nodeId: string,
|
|
189
|
+
appended?: readonly GraphEdge[],
|
|
190
|
+
): Promise<void> {
|
|
191
|
+
let residue = new Set<GraphType>();
|
|
192
|
+
const cleanup = appended
|
|
193
|
+
? removeAppendedNodeEdges(memoryDir, memoryPath, types, appended)
|
|
194
|
+
: removeNodeEdgesForRewrite(memoryDir, memoryPath, types).then((): Set<GraphType> => new Set());
|
|
195
|
+
await cleanup
|
|
196
|
+
.then((left) => {
|
|
197
|
+
residue = left;
|
|
198
|
+
})
|
|
199
|
+
.catch((cleanErr) =>
|
|
200
|
+
log.error(
|
|
201
|
+
`semantic-merge: partial graph edge cleanup failed for ${nodeId} — edges from the failed rebuild remain; rebuild with graph health repair: ${cleanErr instanceof Error ? cleanErr.message : String(cleanErr)}`,
|
|
202
|
+
),
|
|
203
|
+
);
|
|
204
|
+
for (const entry of removed) {
|
|
205
|
+
if (residue.has(entry.type)) {
|
|
206
|
+
log.warn(
|
|
207
|
+
`semantic-merge: skipped ${entry.type} snapshot restore for ${nodeId} — a newer writer's rebuilt edges are live in that graph`,
|
|
208
|
+
);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
await restoreRemovedNodeEdges(memoryDir, entry).catch((restoreErr) =>
|
|
212
|
+
log.error(
|
|
213
|
+
`semantic-merge: graph edge restore failed for ${nodeId} ${entry.type} graph — the prior edges may be lost; rebuild with graph health repair: ${restoreErr instanceof Error ? restoreErr.message : String(restoreErr)}`,
|
|
214
|
+
),
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Round N+14: remove exactly the rows a failed/superseded build appended,
|
|
221
|
+
* then report which of the rewrite types still hold node-generated rows this
|
|
222
|
+
* writer did NOT append (a newer writer's live rebuild) so the caller can
|
|
223
|
+
* skip restoring its older snapshot over them.
|
|
224
|
+
*/
|
|
225
|
+
async function removeAppendedNodeEdges(
|
|
226
|
+
memoryDir: string,
|
|
227
|
+
memoryPath: string,
|
|
228
|
+
types: readonly GraphType[],
|
|
229
|
+
appended: readonly GraphEdge[],
|
|
230
|
+
): Promise<Set<GraphType>> {
|
|
231
|
+
const mineByType = new Map<GraphType, string[]>();
|
|
232
|
+
for (const edge of appended) {
|
|
233
|
+
const list = mineByType.get(edge.type) ?? [];
|
|
234
|
+
list.push(JSON.stringify(edge));
|
|
235
|
+
mineByType.set(edge.type, list);
|
|
236
|
+
}
|
|
237
|
+
const residue = new Set<GraphType>();
|
|
238
|
+
for (const type of types) {
|
|
239
|
+
const filePath = graphFilePath(memoryDir, type);
|
|
240
|
+
const mine = mineByType.get(type) ?? [];
|
|
241
|
+
await withGraphWriteLock(filePath, async (lock) => {
|
|
242
|
+
const edges = await readEdgesStrict(memoryDir, type);
|
|
243
|
+
if (mine.length > 0) {
|
|
244
|
+
const identities = new Set(mine);
|
|
245
|
+
const kept = edges.filter((edge) => !identities.has(JSON.stringify(edge)));
|
|
246
|
+
if (kept.length !== edges.length) {
|
|
247
|
+
// Round N+19 A: lost lock — a peer owns the file. Cleaning it would
|
|
248
|
+
// clobber the peer's write, so leave it, mark the type as residue,
|
|
249
|
+
// and let the caller skip restoring its older snapshot over it
|
|
250
|
+
// (our appended rows may survive as duplicates; graph health
|
|
251
|
+
// repair reconciles). Never old-plus-partial-new over a peer.
|
|
252
|
+
try {
|
|
253
|
+
await assertGraphLockHeld(filePath, lock);
|
|
254
|
+
} catch {
|
|
255
|
+
residue.add(type);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
await writeGraphJsonlAtomic(filePath, kept, lock);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (edges.some((edge) => isNodeGeneratedEdge(edge, type, memoryPath) && !mine.includes(JSON.stringify(edge)))) {
|
|
262
|
+
residue.add(type);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
return residue;
|
|
267
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-process safety of the graph JSONL write lock (issue #2330 round
|
|
3
|
+
* N+18 A). The in-process promise chain cannot see a peer Remnic process
|
|
4
|
+
* sharing the memory directory: a peer append landing between this
|
|
5
|
+
* process's read-snapshot and its rename-backed rewrite was silently
|
|
6
|
+
* discarded by the stale snapshot. Every withGraphWriteLock section must
|
|
7
|
+
* serialize against peers through the shared withHeldFileLock advisory
|
|
8
|
+
* lock (the same primitive the page-versioning manifest uses).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import { spawn } from "node:child_process";
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { mkdir, mkdtemp, readFile, unlink, writeFile } from "node:fs/promises";
|
|
15
|
+
import { randomUUID } from "node:crypto";
|
|
16
|
+
import os from "node:os";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
import { test } from "node:test";
|
|
19
|
+
import { graphFilePath } from "./graph.js";
|
|
20
|
+
import {
|
|
21
|
+
assertGraphLockHeld,
|
|
22
|
+
GraphLockLostError,
|
|
23
|
+
withGraphWriteLock,
|
|
24
|
+
} from "./graph-write-lock.js";
|
|
25
|
+
import { removeNodeEdgesForRewrite, writeGraphJsonlAtomic } from "./graph-jsonl.js";
|
|
26
|
+
|
|
27
|
+
test("withGraphWriteLock: a peer append between read and rewrite is never discarded (round N+18 A)", async () => {
|
|
28
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-graph-xproc-"));
|
|
29
|
+
const jsonlUrl = new URL("./graph-jsonl.ts", import.meta.url).href;
|
|
30
|
+
const graphUrl = new URL("./graph.ts", import.meta.url).href;
|
|
31
|
+
const APPENDS = 60;
|
|
32
|
+
const REWRITES = 30;
|
|
33
|
+
// Large labels widen the read/write windows so the pre-lock race window
|
|
34
|
+
// is exercised on every round, not just occasionally.
|
|
35
|
+
const pad = "y".repeat(2048);
|
|
36
|
+
|
|
37
|
+
// Worker source: plain JS, no nested template literals (tombstones.test.ts
|
|
38
|
+
// pattern). Worker 0 seeds node-owned edges, then alternates
|
|
39
|
+
// removeNodeEdgesForRewrite/restoreRemovedNodeEdges — each round is a
|
|
40
|
+
// read-modify-rename of entity.jsonl. Worker 1 appends distinct edges
|
|
41
|
+
// through appendEdge. Without the cross-process lock, the rewriter's
|
|
42
|
+
// stale snapshot discards appends that land inside its read→rename window.
|
|
43
|
+
const workerSource = [
|
|
44
|
+
"(async () => {",
|
|
45
|
+
"const jsonl = await import(process.argv[1]);",
|
|
46
|
+
"const graph = await import(process.argv[2]);",
|
|
47
|
+
"const dir = process.argv[3];",
|
|
48
|
+
"const workerId = Number(process.argv[4]);",
|
|
49
|
+
"const appends = Number(process.argv[5]);",
|
|
50
|
+
"const rewrites = Number(process.argv[6]);",
|
|
51
|
+
"const pad = process.argv[7];",
|
|
52
|
+
"const node = 'facts/w-a.md';",
|
|
53
|
+
"if (workerId === 0) {",
|
|
54
|
+
" for (let i = 0; i < 3; i += 1) {",
|
|
55
|
+
" await graph.appendEdge(dir, { from: node, to: 'facts/w-a-peer-' + i + '.md', type: 'entity', weight: 1, label: 'seed' + i + pad, ts: new Date().toISOString() });",
|
|
56
|
+
" }",
|
|
57
|
+
" for (let i = 0; i < rewrites; i += 1) {",
|
|
58
|
+
" const removed = await jsonl.removeNodeEdgesForRewrite(dir, node, ['entity']);",
|
|
59
|
+
" for (const entry of removed) await jsonl.restoreRemovedNodeEdges(dir, entry);",
|
|
60
|
+
" }",
|
|
61
|
+
"} else {",
|
|
62
|
+
" for (let i = 0; i < appends; i += 1) {",
|
|
63
|
+
" await graph.appendEdge(dir, { from: 'facts/w-b.md', to: 'facts/w-b-target-' + i + '.md', type: 'entity', weight: 1, label: 'peer' + i + pad, ts: new Date().toISOString() });",
|
|
64
|
+
" }",
|
|
65
|
+
"}",
|
|
66
|
+
"})();",
|
|
67
|
+
].join("\n");
|
|
68
|
+
|
|
69
|
+
function runWorker(workerId: number): Promise<void> {
|
|
70
|
+
// The workers below resolve their modules from argv URLs at runtime —
|
|
71
|
+
// a static import cannot express "the file under test, by URL".
|
|
72
|
+
const { promise, resolve, reject } = Promise.withResolvers<void>();
|
|
73
|
+
const child = spawn(
|
|
74
|
+
process.execPath,
|
|
75
|
+
[
|
|
76
|
+
"--import", "tsx", "-e", workerSource,
|
|
77
|
+
jsonlUrl, graphUrl, dir, String(workerId), String(APPENDS), String(REWRITES), pad,
|
|
78
|
+
],
|
|
79
|
+
{ stdio: ["ignore", "pipe", "pipe"] },
|
|
80
|
+
);
|
|
81
|
+
let stderr = "";
|
|
82
|
+
child.stderr.setEncoding("utf8");
|
|
83
|
+
child.stderr.on("data", (chunk: string) => {
|
|
84
|
+
stderr += chunk;
|
|
85
|
+
});
|
|
86
|
+
child.on("error", reject);
|
|
87
|
+
child.on("close", (code) => {
|
|
88
|
+
if (code === 0) resolve();
|
|
89
|
+
else reject(new Error(`worker ${workerId} exited ${code}: ${stderr}`));
|
|
90
|
+
});
|
|
91
|
+
return promise;
|
|
92
|
+
}
|
|
93
|
+
await Promise.all([runWorker(0), runWorker(1)]);
|
|
94
|
+
|
|
95
|
+
const raw = await readFile(graphFilePath(dir, "entity"), "utf8");
|
|
96
|
+
const rows = raw
|
|
97
|
+
.split("\n")
|
|
98
|
+
.filter((line) => line.trim().length > 0)
|
|
99
|
+
.map((line) => JSON.parse(line) as { from: string });
|
|
100
|
+
const peerAppended = rows.filter((edge) => edge.from === "facts/w-b.md");
|
|
101
|
+
assert.equal(
|
|
102
|
+
peerAppended.length,
|
|
103
|
+
APPENDS,
|
|
104
|
+
`every peer-appended edge must survive the concurrent rewrites (found ${peerAppended.length} of ${APPENDS})`,
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// ── Round N+19 (A): the lock's mtime heartbeat is a timer; it cannot fire
|
|
109
|
+
// while a synchronous parse/serialize blocks the event loop, so a peer can
|
|
110
|
+
// stale-break the lock past the 30s window and publish its own write. A
|
|
111
|
+
// section about to publish must revalidate ownership and abort on loss.
|
|
112
|
+
|
|
113
|
+
test("withGraphWriteLock: refresh reports a peer-replaced lock and the guarded publish refuses (round N+19 A)", async () => {
|
|
114
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-graph-locklost-"));
|
|
115
|
+
const filePath = graphFilePath(dir, "entity");
|
|
116
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
117
|
+
const PEER_ROW = `${JSON.stringify({
|
|
118
|
+
from: "facts/peer.md",
|
|
119
|
+
to: "facts/peer-target.md",
|
|
120
|
+
type: "entity",
|
|
121
|
+
weight: 1,
|
|
122
|
+
label: "peer",
|
|
123
|
+
ts: "2026-08-22T00:00:00.000Z",
|
|
124
|
+
})}\n`;
|
|
125
|
+
await writeFile(filePath, PEER_ROW, "utf8");
|
|
126
|
+
|
|
127
|
+
await withGraphWriteLock(filePath, async (lock) => {
|
|
128
|
+
assert.equal(await lock.refresh(), true, "an unbroken lock refreshes");
|
|
129
|
+
// Simulate the stalled-section consequence: a peer stale-broke our lock
|
|
130
|
+
// and published its own (the row above is its write).
|
|
131
|
+
const lockPath = `${filePath}.lock`;
|
|
132
|
+
await unlink(lockPath).catch(() => undefined);
|
|
133
|
+
await writeFile(lockPath, `${process.pid} peer-${randomUUID()} ${new Date().toISOString()}\n`, "utf8");
|
|
134
|
+
assert.equal(await lock.refresh(), false, "ownership was lost to the peer");
|
|
135
|
+
await assert.rejects(assertGraphLockHeld(filePath, lock), GraphLockLostError);
|
|
136
|
+
assert.equal(await readFile(filePath, "utf8"), PEER_ROW, "the refused publish left the peer's write intact");
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("removeNodeEdgesForRewrite: a stale-broken lock aborts the rewrite instead of clobbering the peer (round N+19 A)", async () => {
|
|
141
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-graph-abort-"));
|
|
142
|
+
const filePath = graphFilePath(dir, "entity");
|
|
143
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
144
|
+
const NODE = "facts/mine.md";
|
|
145
|
+
// A corpus large enough that the section's chunked parse yields to the
|
|
146
|
+
// event loop many times, giving the simulated peer's break a guaranteed
|
|
147
|
+
// landing window inside the section (before the publish guard).
|
|
148
|
+
const rows: string[] = [];
|
|
149
|
+
for (let i = 0; i < 59_999; i += 1) {
|
|
150
|
+
rows.push(
|
|
151
|
+
JSON.stringify({
|
|
152
|
+
from: "facts/other.md",
|
|
153
|
+
to: `facts/x-${i}.md`,
|
|
154
|
+
type: "entity",
|
|
155
|
+
weight: 1,
|
|
156
|
+
label: `row${i}`,
|
|
157
|
+
ts: "2026-08-22T00:00:00.000Z",
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
rows.push(
|
|
162
|
+
JSON.stringify({
|
|
163
|
+
from: NODE,
|
|
164
|
+
to: "facts/mine-target.md",
|
|
165
|
+
type: "entity",
|
|
166
|
+
weight: 1,
|
|
167
|
+
label: "mine",
|
|
168
|
+
ts: "2026-08-22T00:00:00.000Z",
|
|
169
|
+
}),
|
|
170
|
+
);
|
|
171
|
+
await writeFile(filePath, `${rows.join("\n")}\n`, "utf8");
|
|
172
|
+
|
|
173
|
+
const lockPath = `${filePath}.lock`;
|
|
174
|
+
const breakAsPeer = (async () => {
|
|
175
|
+
while (!existsSync(lockPath)) await new Promise<void>((resolve) => setImmediate(resolve));
|
|
176
|
+
await unlink(lockPath).catch(() => undefined);
|
|
177
|
+
await writeFile(lockPath, `${process.pid} peer-${randomUUID()} ${new Date().toISOString()}\n`, "utf8");
|
|
178
|
+
})();
|
|
179
|
+
|
|
180
|
+
await assert.rejects(
|
|
181
|
+
removeNodeEdgesForRewrite(dir, NODE, ["entity"]),
|
|
182
|
+
(err: unknown) => err instanceof Error && /lost mid-section/.test(err.message),
|
|
183
|
+
"a rewrite whose lock was stale-broken mid-section must abort, not publish",
|
|
184
|
+
);
|
|
185
|
+
await breakAsPeer;
|
|
186
|
+
const after = await readFile(filePath, "utf8");
|
|
187
|
+
assert.equal(
|
|
188
|
+
after.includes(`"from":"${NODE}"`),
|
|
189
|
+
true,
|
|
190
|
+
"the aborted rewrite must leave the node's edges untouched (the peer that broke the lock owns the file)",
|
|
191
|
+
);
|
|
192
|
+
assert.equal(after.split("\n").filter((line) => line.trim().length > 0).length, 60_000);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test("writeGraphJsonlAtomic: the rename itself revalidates ownership and refuses a broken lock (round N+20 A)", async () => {
|
|
196
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-graph-rename-guard-"));
|
|
197
|
+
const filePath = graphFilePath(dir, "entity");
|
|
198
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
199
|
+
const PEER_ROW = `${JSON.stringify({
|
|
200
|
+
from: "facts/peer.md",
|
|
201
|
+
to: "facts/peer-target.md",
|
|
202
|
+
type: "entity",
|
|
203
|
+
weight: 1,
|
|
204
|
+
label: "peer",
|
|
205
|
+
ts: "2026-08-22T00:00:00.000Z",
|
|
206
|
+
})}\n`;
|
|
207
|
+
await writeFile(filePath, PEER_ROW, "utf8");
|
|
208
|
+
|
|
209
|
+
await withGraphWriteLock(filePath, async (lock) => {
|
|
210
|
+
assert.equal(await lock.refresh(), true, "an unbroken lock refreshes");
|
|
211
|
+
// The N+20 A window: the CALLER's ownership check has passed, then the
|
|
212
|
+
// section stalls past the 30s stale window — a peer breaks the lock and
|
|
213
|
+
// publishes its own write — and the section resumes at the rename.
|
|
214
|
+
const lockPath = `${filePath}.lock`;
|
|
215
|
+
await unlink(lockPath).catch(() => undefined);
|
|
216
|
+
await writeFile(lockPath, `${process.pid} peer-${randomUUID()} ${new Date().toISOString()}\n`, "utf8");
|
|
217
|
+
await assert.rejects(
|
|
218
|
+
writeGraphJsonlAtomic(
|
|
219
|
+
filePath,
|
|
220
|
+
[{ from: "facts/mine.md", to: "facts/mine-target.md", type: "entity", weight: 1, label: "mine", ts: "2026-08-22T00:00:00.000Z" }],
|
|
221
|
+
lock,
|
|
222
|
+
),
|
|
223
|
+
GraphLockLostError,
|
|
224
|
+
"the publish step must revalidate ownership immediately before the rename",
|
|
225
|
+
);
|
|
226
|
+
assert.equal(await readFile(filePath, "utf8"), PEER_ROW, "the refused rename left the peer's write intact");
|
|
227
|
+
});
|
|
228
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-process-safe write lock for graph JSONL files (issue #2330 round
|
|
3
|
+
* N+18 A). Sibling of graph.ts — extracted there so graph.ts stays within
|
|
4
|
+
* its file-size ratchet; graph.ts re-exports {@link withGraphWriteLock}
|
|
5
|
+
* because `@remnic/core/graph` is a public subpath export.
|
|
6
|
+
*
|
|
7
|
+
* Three layers, one per section:
|
|
8
|
+
*
|
|
9
|
+
* 1. An in-process promise chain keyed by JSONL file path (gotcha #40):
|
|
10
|
+
* the append path (`appendEdge`) and the rewrite path used by the decay
|
|
11
|
+
* maintenance job serialize on the same lock. Without this, an
|
|
12
|
+
* extraction can append a new edge between the decay job's
|
|
13
|
+
* read-snapshot and rewrite, silently dropping the appended edge during
|
|
14
|
+
* active traffic (issue #729 / Codex P1).
|
|
15
|
+
*
|
|
16
|
+
* 2. A cross-process advisory lock: the promise chain only serializes THIS
|
|
17
|
+
* process. A peer Remnic process sharing the memory directory could
|
|
18
|
+
* append an edge after this process reads its JSONL snapshot but before
|
|
19
|
+
* the rename-backed rewrite publishes, permanently discarding the
|
|
20
|
+
* peer's edge — so every section also holds the established
|
|
21
|
+
* `withHeldFileLock` advisory lock (the same primitive round N+16 gave
|
|
22
|
+
* the page-versioning manifest) as a sibling `<file>.lock`. A lock that
|
|
23
|
+
* cannot be taken within the bounded wait FAILS the write (strict,
|
|
24
|
+
* matching the manifest): proceeding unsynchronized would reintroduce
|
|
25
|
+
* the lost-write race the lock exists to prevent. Graph write callers
|
|
26
|
+
* are fail-open, so the surfaced error degrades to a logged skip.
|
|
27
|
+
*
|
|
28
|
+
* 3. Ownership revalidation before destructive writes (round N+19 A): the
|
|
29
|
+
* lock's mtime heartbeat is a TIMER — it cannot fire while a
|
|
30
|
+
* synchronous parse/serialize of a large graph blocks the event loop.
|
|
31
|
+
* A peer can then judge the lock stale past the 30s window, break it,
|
|
32
|
+
* and publish its own write. Every section therefore receives the
|
|
33
|
+
* lock's {@link GraphWriteLockSection} controller and MUST pass it to
|
|
34
|
+
* {@link assertGraphLockHeld} immediately before publishing a
|
|
35
|
+
* replacement (or appending): a lost lock aborts THIS write with
|
|
36
|
+
* {@link GraphLockLostError} instead of clobbering the peer's. Long
|
|
37
|
+
* CPU passes inside a section should await {@link
|
|
38
|
+
* yieldForLockHeartbeat} every few thousand rows so the heartbeat
|
|
39
|
+
* timer gets a turn and the section is less likely to be broken in
|
|
40
|
+
* the first place.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import { withHeldFileLock, type HeldFileLockController } from "./utils/serialize-mutations.js";
|
|
44
|
+
|
|
45
|
+
const graphWriteLocks = new Map<string, Promise<void>>();
|
|
46
|
+
|
|
47
|
+
/** Stale-lock window for the cross-process graph lock (crashed holder). */
|
|
48
|
+
const GRAPH_LOCK_STALE_MS = 30_000;
|
|
49
|
+
/** Bounded acquisition wait for the cross-process graph lock. */
|
|
50
|
+
const GRAPH_LOCK_MAX_WAIT_MS = 10_000;
|
|
51
|
+
|
|
52
|
+
/** Control surface handed to a graph write-lock section (round N+19 A). */
|
|
53
|
+
export type GraphWriteLockSection = HeldFileLockController;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A graph write section lost its advisory lock mid-critical-section — a peer
|
|
57
|
+
* stale-broke and replaced it while this process's event loop was blocked.
|
|
58
|
+
* The thrower has NOT published its write; callers treat it like any other
|
|
59
|
+
* write failure (graph callers are fail-open).
|
|
60
|
+
*/
|
|
61
|
+
export class GraphLockLostError extends Error {
|
|
62
|
+
constructor(filePath: string) {
|
|
63
|
+
super(
|
|
64
|
+
`graph: the write lock for ${filePath} was lost mid-section — a peer stale-broke and replaced it; aborting this write instead of clobbering the peer's`,
|
|
65
|
+
);
|
|
66
|
+
this.name = "GraphLockLostError";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Revalidate lock ownership immediately before a destructive graph write.
|
|
72
|
+
* Throws {@link GraphLockLostError} when the lock was broken/replaced, so the
|
|
73
|
+
* caller aborts and leaves the peer's write intact.
|
|
74
|
+
*/
|
|
75
|
+
export async function assertGraphLockHeld(
|
|
76
|
+
filePath: string,
|
|
77
|
+
lock: GraphWriteLockSection,
|
|
78
|
+
): Promise<void> {
|
|
79
|
+
if (!(await lock.refresh())) throw new GraphLockLostError(filePath);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Yield one event-loop turn so the lock's heartbeat timer can fire during a
|
|
84
|
+
* long, CPU-bound parse/serialize/decay pass inside a held graph lock
|
|
85
|
+
* section (round N+19 A). `setImmediate` runs in the check phase, after any
|
|
86
|
+
* due timers, so each yield lets an overdue heartbeat stamp the lock's mtime
|
|
87
|
+
* before a peer judges it stale.
|
|
88
|
+
*/
|
|
89
|
+
export function yieldForLockHeartbeat(): Promise<void> {
|
|
90
|
+
return new Promise<void>((resolve) => setImmediate(resolve));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Run `fn` while holding the write lock for the given graph JSONL file,
|
|
95
|
+
* handing it the section's {@link GraphWriteLockSection} controller.
|
|
96
|
+
*
|
|
97
|
+
* The lock is keyed by absolute file path so concurrent writes to
|
|
98
|
+
* different graph types proceed independently. The chain recovers from
|
|
99
|
+
* rejection (gotcha #40) so a single I/O failure does not poison all
|
|
100
|
+
* future writers, but the original error is still surfaced to the
|
|
101
|
+
* caller of `withGraphWriteLock`. The in-process chain runs INSIDE the
|
|
102
|
+
* cross-process advisory lock, so peers serialize against every section
|
|
103
|
+
* this process runs, one section at a time.
|
|
104
|
+
*/
|
|
105
|
+
export function withGraphWriteLock<T>(
|
|
106
|
+
filePath: string,
|
|
107
|
+
fn: (lock: GraphWriteLockSection) => Promise<T>,
|
|
108
|
+
): Promise<T> {
|
|
109
|
+
const run = () =>
|
|
110
|
+
withHeldFileLock(
|
|
111
|
+
`${filePath}.lock`,
|
|
112
|
+
{ staleMs: GRAPH_LOCK_STALE_MS, maxWaitMs: GRAPH_LOCK_MAX_WAIT_MS },
|
|
113
|
+
(acquired, lock) => {
|
|
114
|
+
if (!acquired) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
`graph: could not acquire the graph write lock for ${filePath} within ${GRAPH_LOCK_MAX_WAIT_MS}ms — another process holds it`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
return fn(lock);
|
|
120
|
+
},
|
|
121
|
+
);
|
|
122
|
+
const prev = graphWriteLocks.get(filePath) ?? Promise.resolve();
|
|
123
|
+
const next = prev.then(run, run);
|
|
124
|
+
graphWriteLocks.set(
|
|
125
|
+
filePath,
|
|
126
|
+
next.then(
|
|
127
|
+
() => undefined,
|
|
128
|
+
() => undefined
|
|
129
|
+
)
|
|
130
|
+
);
|
|
131
|
+
return next;
|
|
132
|
+
}
|