@remnic/core 9.45.3 → 9.45.4
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/abort-error.d.ts +2 -1
- package/dist/abort-error.js +3 -1
- package/dist/access-admin-ops-surface.d.ts +14 -10
- package/dist/access-admin-ops-surface.js +84 -76
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +14 -10
- package/dist/access-authorization-probe.js +85 -77
- package/dist/access-boundary.d.ts +15 -11
- package/dist/access-boundary.js +84 -76
- package/dist/access-citation-namespace.js +2 -2
- package/dist/access-cli.js +193 -181
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +16 -0
- package/dist/access-coding-context-resolution.js +13 -0
- package/dist/access-coding-context-resolution.js.map +1 -0
- package/dist/access-extraction-force-flush.d.ts +14 -10
- package/dist/access-extraction-force-flush.js +84 -76
- package/dist/access-health-types.d.ts +2 -1
- package/dist/access-http-lcm-compaction.d.ts +16 -12
- package/dist/access-http-lcm-compaction.js +3 -3
- package/dist/access-http-lifecycle-flush.d.ts +14 -10
- package/dist/access-http-lifecycle-flush.js +2 -2
- package/dist/access-http-offline-stream.d.ts +123 -0
- package/dist/access-http-offline-stream.js +10 -0
- package/dist/access-http-offline-stream.js.map +1 -0
- package/dist/access-http-query.js +84 -76
- package/dist/access-http.d.ts +15 -10
- package/dist/access-http.js +105 -92
- package/dist/access-identity-continuity-surface.d.ts +9 -8
- package/dist/access-identity-continuity-surface.js +84 -76
- package/dist/access-lcm-surface.d.ts +14 -10
- package/dist/access-lcm-surface.js +84 -76
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +14 -10
- package/dist/access-mcp.js +95 -83
- package/dist/access-memory-search-fanout.d.ts +3 -2
- package/dist/{access-namespace-preflight-5yZ4g6F8.d.ts → access-namespace-preflight-CWUDwB4M.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +4 -3
- package/dist/access-namespace-preflight.js +84 -76
- package/dist/access-observe-helpers.d.ts +1 -0
- package/dist/access-observe-helpers.js +1 -1
- package/dist/access-observe-write-surface.d.ts +16 -10
- package/dist/access-observe-write-surface.js +84 -76
- package/dist/access-offline-manifest.d.ts +104 -0
- package/dist/access-offline-manifest.js +45 -0
- package/dist/access-offline-manifest.js.map +1 -0
- package/dist/access-operations-batch.js +86 -78
- package/dist/access-operations.d.ts +15 -11
- package/dist/access-operations.js +91 -80
- package/dist/access-recall-concurrency.d.ts +16 -26
- package/dist/access-recall-concurrency.js +86 -77
- package/dist/access-recall-response.d.ts +18 -14
- package/dist/access-recall-response.js +84 -76
- package/dist/access-recall-surface.d.ts +29 -24
- package/dist/access-recall-surface.js +84 -76
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-CiJRsgAB.d.ts → access-service-CsU-ljFD.d.ts} +25 -16
- package/dist/access-service-helpers.d.ts +14 -10
- package/dist/access-service.d.ts +14 -10
- package/dist/access-service.js +84 -76
- package/dist/access-surface-catalog.d.ts +14 -10
- package/dist/access-surface-catalog.js +4 -0
- 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 +10 -8
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/{auto-sync-5OE5QOZB.js → auto-sync-UPTUVE4X.js} +6 -6
- package/dist/behavior-learner.d.ts +2 -1
- package/dist/behavior-learner.js +1 -1
- package/dist/behavior-signals.d.ts +2 -1
- package/dist/bootstrap.d.ts +9 -8
- package/dist/briefing.d.ts +3 -2
- package/dist/briefing.js +23 -22
- 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 +12 -11
- package/dist/bulk-import/index.d.ts +4 -3
- package/dist/calibration.d.ts +2 -1
- package/dist/capabilities.d.ts +2 -1
- package/dist/{capsule-merge-IDWJPCWK.js → capsule-merge-Q6AR3XL7.js} +67 -54
- package/dist/capsule-merge-Q6AR3XL7.js.map +1 -0
- package/dist/{catalog-scBmy0sO.d.ts → catalog-bctMURhN.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +2 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +2 -1
- package/dist/causal-consolidation.js +27 -26
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +2 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-VUPTKTDV.js → chunk-2MRHJNWL.js} +3 -3
- package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
- package/dist/{chunk-5IVLTFOV.js → chunk-44N6ESJ4.js} +2 -2
- package/dist/{chunk-WOCNN776.js → chunk-4POAMKV6.js} +100 -41
- package/dist/chunk-4POAMKV6.js.map +1 -0
- package/dist/{chunk-HO3QBJEY.js → chunk-5546W5SI.js} +2 -2
- package/dist/{chunk-U7GW7NE7.js → chunk-5CEECY6P.js} +10 -10
- package/dist/{chunk-4UH4BTGK.js → chunk-5SNZSWWR.js} +82 -82
- package/dist/{chunk-6CZPDBJS.js → chunk-5U7ID3EZ.js} +3 -3
- package/dist/{chunk-GF22HWS2.js → chunk-6NNNURLK.js} +7 -7
- package/dist/chunk-773TRRGT.js +36 -0
- package/dist/chunk-773TRRGT.js.map +1 -0
- package/dist/chunk-7CITSYSH.js +242 -0
- package/dist/chunk-7CITSYSH.js.map +1 -0
- package/dist/{chunk-227UFSEQ.js → chunk-7RZJWZ46.js} +5 -5
- package/dist/{chunk-E5UK4VPE.js → chunk-7SHJHPTY.js} +5 -5
- package/dist/{chunk-UVIKWC7M.js → chunk-7YERSTN7.js} +17 -17
- package/dist/{chunk-DLVPUX7U.js → chunk-7YKVM5H3.js} +8 -6
- package/dist/chunk-7YKVM5H3.js.map +1 -0
- package/dist/{chunk-3CE77VAP.js → chunk-A4JMGKCD.js} +87 -74
- package/dist/chunk-A4JMGKCD.js.map +1 -0
- package/dist/chunk-A5KNZSNA.js +26 -0
- package/dist/chunk-A5KNZSNA.js.map +1 -0
- package/dist/{chunk-S2NCTZGJ.js → chunk-AJQ57VV3.js} +15 -15
- package/dist/chunk-AJQ57VV3.js.map +1 -0
- package/dist/{chunk-CUM2BBPN.js → chunk-AUMWZSE7.js} +19 -10
- package/dist/chunk-AUMWZSE7.js.map +1 -0
- package/dist/{chunk-XYTOI63Z.js → chunk-BGHFOD5A.js} +19 -11
- package/dist/chunk-BGHFOD5A.js.map +1 -0
- package/dist/{chunk-BUE5E2HL.js → chunk-BGLY7EEM.js} +5 -314
- package/dist/chunk-BGLY7EEM.js.map +1 -0
- package/dist/chunk-BIPBQQFI.js +44 -0
- package/dist/chunk-BIPBQQFI.js.map +1 -0
- package/dist/{chunk-S5SLVSVY.js → chunk-BQIFZ2MP.js} +5 -5
- package/dist/chunk-BTTPKDIL.js +34 -0
- package/dist/{chunk-PVGDJXVK.js.map → chunk-BTTPKDIL.js.map} +1 -1
- package/dist/{chunk-E53DSZEN.js → chunk-C26TE27X.js} +3 -3
- package/dist/{chunk-LZ4LDKHZ.js → chunk-CLB32OHM.js} +6 -6
- package/dist/{chunk-Q6IP2ARR.js → chunk-CSOYVTRX.js} +2 -2
- package/dist/{chunk-XOQSEF7X.js → chunk-CVILPI77.js} +6 -6
- package/dist/chunk-D3I2MCN7.js +29 -0
- package/dist/chunk-D3I2MCN7.js.map +1 -0
- package/dist/{chunk-A5OJCXZL.js → chunk-DSUAAZZX.js} +15 -4
- package/dist/chunk-DSUAAZZX.js.map +1 -0
- package/dist/{chunk-HREE4JHI.js → chunk-DYVMXPCF.js} +486 -287
- package/dist/chunk-DYVMXPCF.js.map +1 -0
- package/dist/{chunk-J7VGGECD.js → chunk-DZPFMQZ7.js} +1 -1
- package/dist/chunk-DZPFMQZ7.js.map +1 -0
- package/dist/{chunk-PDLBLTOK.js → chunk-EITZHSX6.js} +9 -9
- package/dist/{chunk-D3J5SLQK.js → chunk-EJHEWCGQ.js} +81 -20
- package/dist/chunk-EJHEWCGQ.js.map +1 -0
- package/dist/{chunk-WUNIWKY4.js → chunk-ELIL2A37.js} +6 -6
- package/dist/{chunk-E6PNLPGJ.js → chunk-FZP32336.js} +806 -470
- package/dist/chunk-FZP32336.js.map +1 -0
- package/dist/{chunk-HZFHQ4AQ.js → chunk-G7A5HLUS.js} +23 -17
- package/dist/chunk-G7A5HLUS.js.map +1 -0
- package/dist/{chunk-CINZGPSJ.js → chunk-GUMZC2BO.js} +2 -2
- package/dist/{chunk-H24WNPA2.js → chunk-GWFSVJ4P.js} +3 -3
- package/dist/{chunk-7XC2HX75.js → chunk-GYPQL6XN.js} +157 -16
- package/dist/chunk-GYPQL6XN.js.map +1 -0
- package/dist/{chunk-TSH56VPU.js → chunk-HAYSYUAB.js} +2 -2
- package/dist/{chunk-TDHTVMPG.js → chunk-HFPASSFV.js} +7 -2
- package/dist/chunk-HFPASSFV.js.map +1 -0
- package/dist/chunk-J2WC5LF4.js +395 -0
- package/dist/chunk-J2WC5LF4.js.map +1 -0
- package/dist/{chunk-PKNLM44P.js → chunk-JH6BPLOP.js} +9 -9
- package/dist/{chunk-KXB4VXHY.js → chunk-JIYDRBVZ.js} +2 -2
- package/dist/chunk-JV3C2MNQ.js +74 -0
- package/dist/chunk-JV3C2MNQ.js.map +1 -0
- package/dist/{chunk-AV5ZEH4M.js → chunk-KVJRXN2E.js} +2 -2
- package/dist/{chunk-JVLCVFQ4.js → chunk-KXEFRMCF.js} +3 -3
- package/dist/{chunk-WFTIGIIS.js → chunk-L6CQ7WIW.js} +5 -5
- package/dist/{chunk-EJUEXZHX.js → chunk-LLJMAULE.js} +2 -2
- package/dist/{chunk-N5Z4EVOR.js → chunk-LNEWDF2A.js} +36 -11
- package/dist/chunk-LNEWDF2A.js.map +1 -0
- package/dist/{chunk-AS7YMSL6.js → chunk-M23RF3LJ.js} +4 -4
- package/dist/{chunk-UYLMNVY6.js → chunk-MDISBSYA.js} +16 -9
- package/dist/chunk-MDISBSYA.js.map +1 -0
- package/dist/{chunk-3F2LKUMU.js → chunk-NIS256NW.js} +2 -2
- package/dist/{chunk-YIAA2X3D.js → chunk-NK5RGJ65.js} +3 -3
- package/dist/chunk-NLDVVWCL.js +84 -0
- package/dist/chunk-NLDVVWCL.js.map +1 -0
- package/dist/{chunk-OQ5PRDDS.js → chunk-NTOIP2E6.js} +6 -6
- package/dist/{chunk-HLPD7B7P.js → chunk-NUEQKLNB.js} +2 -2
- package/dist/{chunk-4J7G5SY4.js → chunk-NZBZ7IS2.js} +72 -24
- package/dist/chunk-NZBZ7IS2.js.map +1 -0
- package/dist/{chunk-3TBLDMJA.js → chunk-O4KMGRXE.js} +5 -2
- package/dist/chunk-O4KMGRXE.js.map +1 -0
- package/dist/{chunk-33PLLLL7.js → chunk-P7NGM24P.js} +6 -6
- package/dist/{chunk-7TWUCYER.js → chunk-PNRA7FAD.js} +7 -7
- package/dist/{chunk-5I4M26Q7.js → chunk-QBSFOKY6.js} +4 -4
- package/dist/{chunk-QJAQNXWI.js → chunk-QCECHYZL.js} +76 -79
- package/dist/chunk-QCECHYZL.js.map +1 -0
- package/dist/{chunk-P4DRWEYC.js → chunk-QVSBTCVP.js} +2 -2
- package/dist/{chunk-AAIUERNB.js → chunk-R5RFK3CB.js} +6 -6
- package/dist/{chunk-WDISJRMG.js → chunk-RMMVQQA6.js} +2 -2
- package/dist/{chunk-KWMXR7XS.js → chunk-S2V7RUCL.js} +8 -1
- package/dist/{chunk-KWMXR7XS.js.map → chunk-S2V7RUCL.js.map} +1 -1
- package/dist/{chunk-5SM35XZR.js → chunk-S5NZBKKQ.js} +2 -2
- package/dist/{chunk-VNA7W7QF.js → chunk-SVH57F5Z.js} +12 -4
- package/dist/chunk-SVH57F5Z.js.map +1 -0
- package/dist/{chunk-WIPEXG6R.js → chunk-SXIMQLGV.js} +2 -2
- package/dist/{chunk-RVLJEII5.js → chunk-SYUBB3WM.js} +256 -187
- package/dist/chunk-SYUBB3WM.js.map +1 -0
- package/dist/{chunk-OAEQLRCY.js → chunk-TN76AKO3.js} +5 -5
- package/dist/{chunk-QN25OCUF.js → chunk-TQ4GD737.js} +5 -5
- package/dist/{chunk-VCD4PSK2.js → chunk-TQZ4DVBC.js} +7 -4
- package/dist/chunk-TQZ4DVBC.js.map +1 -0
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-DNWXFTLD.js → chunk-TYISDI6B.js} +2 -2
- package/dist/{chunk-4LMA77JH.js → chunk-U2VLVBBH.js} +3 -3
- package/dist/{chunk-5ZE7QHTK.js → chunk-ULVR5KG7.js} +5 -5
- package/dist/{chunk-NVRYW264.js → chunk-UQWIKLQK.js} +18 -15
- package/dist/chunk-UQWIKLQK.js.map +1 -0
- package/dist/{chunk-YV32N67O.js → chunk-URS5GSM7.js} +1 -1
- package/dist/chunk-URS5GSM7.js.map +1 -0
- package/dist/{chunk-4B77XSG5.js → chunk-UV72DEZD.js} +5 -5
- package/dist/{chunk-S2BBISHU.js → chunk-VANZKHTN.js} +3 -3
- package/dist/chunk-VHFXP27N.js +250 -0
- package/dist/chunk-VHFXP27N.js.map +1 -0
- package/dist/{chunk-3Y224NYC.js → chunk-VYISFWVX.js} +2 -2
- package/dist/{chunk-TIHMZFIV.js → chunk-W3IC7QOY.js} +3 -3
- package/dist/{chunk-NRV4Y3PM.js → chunk-W4FBGYGK.js} +1 -1
- package/dist/{chunk-P2BM76KT.js → chunk-WAS4HV46.js} +174 -43
- package/dist/chunk-WAS4HV46.js.map +1 -0
- package/dist/{chunk-57QKLRBV.js → chunk-WB7JSQCP.js} +2 -1
- package/dist/chunk-WB7JSQCP.js.map +1 -0
- package/dist/chunk-WGP57SR3.js +68 -0
- package/dist/chunk-WGP57SR3.js.map +1 -0
- package/dist/{chunk-ECK75GDJ.js → chunk-WQIHRA5F.js} +43 -24
- package/dist/chunk-WQIHRA5F.js.map +1 -0
- package/dist/{chunk-MU7ZHSZE.js → chunk-WZFAPHIK.js} +2 -2
- package/dist/{chunk-T2TTP3KU.js → chunk-X4IDNPOS.js} +2 -2
- package/dist/{chunk-BLAKS3CP.js → chunk-XL3TATMJ.js} +3 -3
- package/dist/{chunk-W4XJFLAL.js → chunk-XPRJSHNI.js} +2 -2
- package/dist/{chunk-5TFP4CUL.js → chunk-XQ3HXAQH.js} +14 -11
- package/dist/chunk-XQ3HXAQH.js.map +1 -0
- package/dist/{chunk-VWAXN2BN.js → chunk-XSFHWBQO.js} +93 -31
- package/dist/chunk-XSFHWBQO.js.map +1 -0
- package/dist/{chunk-DL7ZD3JH.js → chunk-XTAUXTDO.js} +14 -9
- package/dist/chunk-XTAUXTDO.js.map +1 -0
- package/dist/{chunk-JE7EK33X.js → chunk-Y7HRYCNW.js} +2 -2
- package/dist/{chunk-E6EE5B67.js → chunk-YK6BDDHP.js} +4 -4
- package/dist/{chunk-ES36HTSC.js → chunk-YLHM5BQQ.js} +3 -3
- package/dist/{chunk-RN7DY3FC.js → chunk-YMAQDHQM.js} +31 -12
- package/dist/chunk-YMAQDHQM.js.map +1 -0
- package/dist/{chunk-ULARSG5Z.js → chunk-YN6ASZUG.js} +10 -8
- package/dist/{chunk-ULARSG5Z.js.map → chunk-YN6ASZUG.js.map} +1 -1
- package/dist/{chunk-IKKWIPYN.js → chunk-YYQAKIDJ.js} +37 -1
- package/dist/chunk-YYQAKIDJ.js.map +1 -0
- package/dist/{chunk-BJKPPZ6Z.js → chunk-ZFGZ6PZ2.js} +2 -2
- package/dist/{chunk-CJ2ZR7UA.js → chunk-ZI32MKDW.js} +267 -214
- package/dist/chunk-ZI32MKDW.js.map +1 -0
- package/dist/{chunk-64UDOIMI.js → chunk-ZLQ37WJX.js} +2 -2
- package/dist/chunk-ZMAYKGPN.js +351 -0
- package/dist/chunk-ZMAYKGPN.js.map +1 -0
- package/dist/{cli-BUGN3d6_.d.ts → cli-BBHDtG36.d.ts} +5 -5
- package/dist/cli.d.ts +16 -12
- package/dist/cli.js +138 -124
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +24 -23
- 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 +10 -8
- package/dist/connectors/codex-materialize-runner.d.ts +2 -1
- package/dist/connectors/codex-materialize-runner.js +23 -22
- package/dist/connectors/codex-materialize.d.ts +2 -1
- package/dist/connectors/index.d.ts +2 -1
- package/dist/connectors/index.js +26 -25
- 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 +10 -7
- package/dist/consolidation-undo.js.map +1 -1
- package/dist/contradiction/index.d.ts +3 -2
- package/dist/converge-config.d.ts +2 -1
- package/dist/convergence-refresh.d.ts +4 -3
- package/dist/convergence-refresh.js +27 -26
- package/dist/conversation-index/backend.d.ts +2 -1
- package/dist/conversation-index/backend.js +2 -2
- 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 +42 -41
- package/dist/day-summary.d.ts +2 -1
- package/dist/delinearize.d.ts +2 -1
- package/dist/direct-answer-wiring.d.ts +2 -1
- package/dist/direct-answer-wiring.js +2 -2
- package/dist/direct-answer.d.ts +2 -1
- package/dist/embedding-fallback.d.ts +2 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +2 -1
- package/dist/entity-retrieval-boundaries.js +1 -1
- package/dist/entity-retrieval.d.ts +3 -2
- package/dist/entity-retrieval.js +24 -23
- package/dist/entity-schema.d.ts +2 -1
- package/dist/explicit-capture.d.ts +9 -8
- package/dist/explicit-capture.js +11 -9
- package/dist/external-wiki-access.d.ts +127 -0
- package/dist/external-wiki-access.js +186 -0
- package/dist/external-wiki-access.js.map +1 -0
- package/dist/external-wiki-cli.d.ts +13 -0
- package/dist/external-wiki-cli.js +96 -0
- package/dist/external-wiki-cli.js.map +1 -0
- package/dist/external-wiki-collection-registration.d.ts +39 -0
- package/dist/external-wiki-collection-registration.js +79 -0
- package/dist/external-wiki-collection-registration.js.map +1 -0
- package/dist/external-wiki-collection.d.ts +50 -0
- package/dist/external-wiki-collection.js +387 -0
- package/dist/external-wiki-collection.js.map +1 -0
- package/dist/external-wiki-config.d.ts +13 -0
- package/dist/external-wiki-config.js +13 -0
- package/dist/external-wiki-config.js.map +1 -0
- package/dist/external-wiki-guard.d.ts +11 -0
- package/dist/external-wiki-guard.js +18 -0
- package/dist/external-wiki-guard.js.map +1 -0
- package/dist/external-wiki-mcp-tools.d.ts +123 -0
- package/dist/external-wiki-mcp-tools.js +8 -0
- package/dist/external-wiki-mcp-tools.js.map +1 -0
- package/dist/external-wiki-search.d.ts +42 -0
- package/dist/external-wiki-search.js +11 -0
- package/dist/external-wiki-search.js.map +1 -0
- package/dist/external-wiki.d.ts +43 -0
- package/dist/external-wiki.js +16 -0
- package/dist/external-wiki.js.map +1 -0
- 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-source-grounding-helpers.d.ts +5 -3
- package/dist/extraction-source-grounding-helpers.js +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +2 -1
- package/dist/extraction-source-grounding-rules.js +2 -2
- package/dist/extraction-source-grounding.d.ts +2 -1
- package/dist/extraction-source-grounding.js +5 -5
- package/dist/extraction.d.ts +2 -1
- package/dist/extraction.js +45 -43
- package/dist/fallback-llm.d.ts +2 -1
- package/dist/graph-dashboard-diff.d.ts +2 -1
- package/dist/graph-dashboard-key.d.ts +2 -1
- package/dist/graph-dashboard-parser.d.ts +2 -1
- package/dist/graph-edge-reinforcement.d.ts +2 -1
- package/dist/graph-snapshot.d.ts +2 -1
- package/dist/graph.d.ts +2 -1
- package/dist/harmonic-retrieval.js +2 -2
- 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.d.ts +362 -350
- package/dist/index.js +291 -259
- package/dist/intent.d.ts +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 +8 -8
- 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/local-llm.d.ts +2 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +2 -1
- package/dist/maintenance/memory-governance.d.ts +2 -1
- package/dist/maintenance/memory-governance.js +24 -23
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +24 -23
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +26 -25
- package/dist/{maintenance-LbuS2rUA.d.ts → maintenance-D2mveyCd.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +14 -10
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +2 -1
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-projection-store.d.ts +2 -1
- package/dist/memory-provenance.d.ts +2 -1
- 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 +40 -39
- package/dist/namespaces/principal.d.ts +2 -1
- package/dist/namespaces/search.d.ts +2 -1
- package/dist/namespaces/search.js +18 -18
- package/dist/namespaces/storage.d.ts +4 -3
- package/dist/namespaces/storage.js +23 -22
- package/dist/native-knowledge.d.ts +2 -1
- package/dist/offline-sync-impression-drain.d.ts +2 -1
- package/dist/offline-sync-impression-drain.js +11 -9
- package/dist/offline-sync.d.ts +29 -3
- package/dist/offline-sync.js +6 -2
- package/dist/operator-doctor-corpus.d.ts +2 -1
- package/dist/operator-doctor-corpus.js +45 -44
- package/dist/operator-doctor-replica.d.ts +2 -1
- package/dist/operator-doctor-replica.js +3 -3
- package/dist/operator-toolkit.d.ts +4 -3
- package/dist/operator-toolkit.js +59 -55
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +36 -33
- package/dist/{orchestrator-rHiWt32X.d.ts → orchestrator-DJYlwiUv.d.ts} +14 -7
- package/dist/orchestrator.d.ts +9 -8
- package/dist/orchestrator.js +201 -189
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +2 -1
- package/dist/{pipeline-W_97O8BV.d.ts → pipeline-CNjY4wk3.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +2 -1
- package/dist/policy-runtime.js +1 -1
- package/dist/proactive-contention.d.ts +2 -1
- package/dist/provenance.d.ts +2 -1
- package/dist/provenance.js +2 -2
- package/dist/{qmd-LWtMofAf.d.ts → qmd-C0UDZidt.d.ts} +9 -7
- package/dist/qmd-preflight.d.ts +5 -4
- package/dist/qmd-preflight.js +2 -2
- package/dist/qmd-recall-cache.d.ts +2 -1
- package/dist/qmd.d.ts +4 -3
- package/dist/qmd.js +5 -5
- 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-planner-llm.d.ts +2 -1
- package/dist/recall-state.d.ts +2 -1
- 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 +8 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +12 -2
- package/dist/reconcile/cursor.js +46 -7
- package/dist/reconcile/cursor.js.map +1 -1
- package/dist/reconcile/manifest.d.ts +9 -2
- package/dist/reconcile/manifest.js +15 -268
- package/dist/reconcile/manifest.js.map +1 -1
- package/dist/reconcile/plan.d.ts +4 -1
- package/dist/reconcile/plan.js +4 -4
- 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-divergence.js +2 -2
- package/dist/replica-peers-config.d.ts +2 -1
- package/dist/resolve-auth-token.d.ts +2 -1
- package/dist/resume-bundles.js +12 -10
- package/dist/retrieval-agents.d.ts +4 -3
- package/dist/retrieval-agents.js +2 -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/schemas.d.ts +32 -32
- package/dist/{scope-profiles-BiQKOE-p.d.ts → scope-profiles-BJzp2F5A.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +2 -1
- package/dist/search/embed-helper.js +3 -3
- package/dist/search/factory.d.ts +4 -2
- package/dist/search/factory.js +20 -18
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.js +22 -22
- 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 +18 -1
- package/dist/search/port.js +1 -1
- package/dist/search/remote-backend.d.ts +2 -1
- package/dist/search/remote-backend.js +2 -2
- package/dist/secure-store/index.js +2 -2
- package/dist/{semantic-consolidation-dHYCyqgh.d.ts → semantic-consolidation-D4KAZO2G.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +3 -2
- package/dist/semantic-consolidation.js +25 -24
- package/dist/semantic-rule-promotion.js +23 -22
- package/dist/semantic-rule-verifier.d.ts +2 -1
- package/dist/semantic-rule-verifier.js +24 -23
- package/dist/{service-DJG3KCQ4.d.ts → service-BeDxSqE-.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/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +2 -1
- package/dist/source-agent-qualifier.d.ts +2 -1
- package/dist/source-agent-qualifier.js +42 -40
- package/dist/{storage-F9FVh-w9.d.ts → storage-DfjxusTE.d.ts} +24 -12
- package/dist/storage.d.ts +3 -2
- package/dist/storage.js +25 -24
- package/dist/summarizer.d.ts +2 -1
- package/dist/summarizer.js +5 -5
- package/dist/summary-snapshot.d.ts +2 -1
- 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/tool-scoped-memory.d.ts +5 -1
- package/dist/tool-scoped-memory.js +3 -1
- package/dist/topics.d.ts +2 -1
- package/dist/transcript.d.ts +2 -1
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +2 -1
- package/dist/trust-score.d.ts +2 -1
- package/dist/{types-rEwubvim.d.ts → types-yX_FwERf.d.ts} +8 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +2 -1
- package/dist/verified-recall.js +24 -23
- package/dist/write-envelope.d.ts +2 -1
- package/package.json +2 -2
- package/src/abort-error.ts +17 -0
- package/src/access-admin-ops-surface.ts +1 -0
- package/src/access-boundary.ts +1 -0
- package/src/access-coding-context-resolution.ts +42 -0
- package/src/access-extraction-force-flush.ts +38 -2
- package/src/access-http-lcm-compaction.ts +5 -2
- package/src/access-http-offline-stream.ts +79 -0
- package/src/access-http.test.ts +310 -3
- package/src/access-http.ts +85 -21
- package/src/access-mcp-output-schemas.ts +36 -0
- package/src/access-mcp.test.ts +95 -1
- package/src/access-mcp.ts +7 -9
- package/src/access-observe-helpers.ts +64 -22
- package/src/access-observe-write-surface.ts +8 -0
- package/src/access-offline-manifest.ts +54 -0
- package/src/access-operations-batch.ts +3 -3
- package/src/access-operations.ts +13 -7
- package/src/access-recall-concurrency.ts +3 -27
- package/src/access-recall-surface.ts +3 -0
- package/src/access-service-health.test.ts +32 -7
- package/src/access-service-namespace.test.ts +55 -0
- package/src/access-service-observe-idempotency.test.ts +34 -2
- package/src/access-service-observe-lcm-parity.test.ts +138 -3
- package/src/access-service-observe-scope.test.ts +160 -1
- package/src/access-service-offline-file-content.test.ts +345 -1
- package/src/access-service.ts +86 -59
- package/src/access-surface-catalog.ts +4 -0
- package/src/admin/admin-surfaces.ts +2 -0
- package/src/binary-lifecycle/pipeline.test.ts +106 -1
- package/src/binary-lifecycle/pipeline.ts +3 -0
- package/src/coding/git-context.test.ts +47 -0
- package/src/coding/git-context.ts +129 -27
- package/src/config.test.ts +24 -0
- package/src/config.ts +9 -12
- package/src/connector-provenance.test.ts +101 -0
- package/src/consolidation-undo.ts +3 -0
- package/src/convergence-refresh.ts +14 -2
- package/src/correction/correction-access-wiring.ts +9 -7
- package/src/correction/correction-executor.test.ts +206 -2
- package/src/correction/correction-executor.ts +29 -20
- package/src/correction/correction-planner.test.ts +36 -0
- package/src/correction/correction-planner.ts +9 -15
- package/src/correction/correction-service.ts +3 -1
- package/src/correction/correction-storage-integration.test.ts +77 -0
- package/src/correction/correction-surfaces.test.ts +41 -28
- package/src/correction/passive-capture.test.ts +59 -0
- package/src/correction/passive-capture.ts +4 -1
- package/src/entity-retrieval-boundaries.ts +17 -4
- package/src/entity-retrieval.ts +27 -6
- package/src/external-wiki-access.test.ts +65 -0
- package/src/external-wiki-access.ts +31 -0
- package/src/external-wiki-cli.ts +92 -0
- package/src/external-wiki-collection-registration.test.ts +163 -0
- package/src/external-wiki-collection-registration.ts +101 -0
- package/src/external-wiki-collection.test.ts +502 -0
- package/src/external-wiki-collection.ts +503 -0
- package/src/external-wiki-config.test.ts +135 -0
- package/src/external-wiki-config.ts +100 -0
- package/src/external-wiki-guard.ts +83 -0
- package/src/external-wiki-mcp-tools.ts +23 -0
- package/src/external-wiki-search.test.ts +301 -0
- package/src/external-wiki-search.ts +362 -0
- package/src/external-wiki.test.ts +240 -0
- package/src/external-wiki.ts +453 -0
- package/src/extraction-scope-source-agent.test.ts +21 -0
- package/src/extraction-source-grounding-helpers.ts +243 -53
- package/src/extraction-source-grounding-rules.ts +133 -39
- package/src/extraction-source-grounding.test.ts +363 -33
- package/src/extraction-timeout.test.ts +1 -0
- package/src/extraction-watermark.test.ts +150 -7
- package/src/extraction.ts +8 -1
- package/src/index.ts +8 -0
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/offline-sync.test.ts +194 -0
- package/src/offline-sync.ts +217 -13
- package/src/orchestration/external-wiki-recall-guard.test.ts +94 -0
- package/src/orchestration/extraction-persist.ts +19 -2
- package/src/orchestration/extraction-run-helpers.ts +37 -19
- package/src/orchestration/extraction-run.test.ts +171 -2
- package/src/orchestration/extraction-run.ts +11 -13
- package/src/orchestration/extraction-watermark.ts +106 -17
- package/src/orchestration/generic-recall-paths.ts +14 -0
- package/src/orchestration/orchestrator-helpers.ts +2 -0
- package/src/orchestration/orchestrator-init.ts +9 -0
- package/src/orchestration/recall-internal-deps.ts +6 -0
- package/src/orchestration/recall-internal.ts +154 -33
- package/src/orchestration/recall-rerank-coordinator.ts +60 -25
- package/src/orchestration/recall-search-pipeline.test.ts +75 -1
- package/src/orchestration/recall-search-pipeline.ts +50 -10
- package/src/orchestrator-convergence-refresh.test.ts +36 -2
- package/src/orchestrator.ts +13 -3
- package/src/page-versioning.ts +5 -19
- package/src/procedural/procedure-recall.ts +5 -1
- package/src/provenance-surfaces.test.ts +3 -0
- package/src/qmd-client.test.ts +78 -17
- package/src/qmd.test.ts +24 -0
- package/src/qmd.ts +224 -315
- package/src/recall-explain-renderer.ts +3 -0
- package/src/recall-rerank-coordinator.test.ts +61 -0
- package/src/recall-xray-renderer.test.ts +6 -0
- package/src/recall-xray.test.ts +88 -1
- package/src/recall-xray.ts +15 -0
- package/src/reconcile/cursor.test.ts +48 -0
- package/src/reconcile/cursor.ts +58 -11
- package/src/reconcile/manifest.test.ts +4 -0
- package/src/reconcile/manifest.ts +41 -51
- package/src/reconcile/plan.test.ts +4 -0
- package/src/reconcile/plan.ts +28 -16
- package/src/search/factory.ts +6 -6
- package/src/search/port.ts +25 -9
- package/src/secure-store/secure-fs.ts +20 -12
- package/src/secure-store/secure-store.test.ts +41 -2
- package/src/spaces/index.test.ts +61 -2
- package/src/spaces/index.ts +44 -18
- package/src/storage/entity-alias-config.ts +97 -0
- package/src/storage/entity-canonical-id-lock.ts +53 -23
- package/src/storage/entity-canonical-id-migration.ts +53 -22
- package/src/storage/entity-canonical-id-references.ts +3 -0
- package/src/storage/entity-id-safety.ts +7 -0
- package/src/storage/entity-store.ts +6 -2
- package/src/storage/memory-frontmatter-metadata.ts +4 -9
- package/src/storage/memory-migration-serialization.ts +10 -15
- package/src/storage/tombstone-blocked-capture-mutation.ts +52 -64
- package/src/storage/tombstone-blocked-capture-sync.ts +244 -199
- package/src/storage-deletion-revisions.test.ts +91 -0
- package/src/storage-fact-hash-index-defer.test.ts +446 -163
- package/src/storage.ts +534 -245
- package/src/tool-scoped-memory.ts +10 -0
- package/src/transfer/capsule-import.ts +13 -0
- package/src/transfer/capsule-merge.ts +13 -0
- package/src/trust-score-recall-paths.test.ts +75 -1
- package/src/types.ts +7 -3
- package/dist/capsule-merge-IDWJPCWK.js.map +0 -1
- package/dist/chunk-3CE77VAP.js.map +0 -1
- package/dist/chunk-3TBLDMJA.js.map +0 -1
- package/dist/chunk-4J7G5SY4.js.map +0 -1
- package/dist/chunk-57QKLRBV.js.map +0 -1
- package/dist/chunk-5TFP4CUL.js.map +0 -1
- package/dist/chunk-7XC2HX75.js.map +0 -1
- package/dist/chunk-A5OJCXZL.js.map +0 -1
- package/dist/chunk-BUE5E2HL.js.map +0 -1
- package/dist/chunk-CJ2ZR7UA.js.map +0 -1
- package/dist/chunk-CUM2BBPN.js.map +0 -1
- package/dist/chunk-D3J5SLQK.js.map +0 -1
- package/dist/chunk-DL7ZD3JH.js.map +0 -1
- package/dist/chunk-DLVPUX7U.js.map +0 -1
- package/dist/chunk-E6PNLPGJ.js.map +0 -1
- package/dist/chunk-ECK75GDJ.js.map +0 -1
- package/dist/chunk-HREE4JHI.js.map +0 -1
- package/dist/chunk-HZFHQ4AQ.js.map +0 -1
- package/dist/chunk-IKKWIPYN.js.map +0 -1
- package/dist/chunk-J7VGGECD.js.map +0 -1
- package/dist/chunk-N5Z4EVOR.js.map +0 -1
- package/dist/chunk-NVRYW264.js.map +0 -1
- package/dist/chunk-P2BM76KT.js.map +0 -1
- package/dist/chunk-PVGDJXVK.js +0 -21
- package/dist/chunk-QJAQNXWI.js.map +0 -1
- package/dist/chunk-RN7DY3FC.js.map +0 -1
- package/dist/chunk-RVLJEII5.js.map +0 -1
- package/dist/chunk-S2NCTZGJ.js.map +0 -1
- package/dist/chunk-TDHTVMPG.js.map +0 -1
- package/dist/chunk-UYLMNVY6.js.map +0 -1
- package/dist/chunk-VCD4PSK2.js.map +0 -1
- package/dist/chunk-VNA7W7QF.js.map +0 -1
- package/dist/chunk-VWAXN2BN.js.map +0 -1
- package/dist/chunk-WOCNN776.js.map +0 -1
- package/dist/chunk-XYTOI63Z.js.map +0 -1
- package/dist/chunk-YV32N67O.js.map +0 -1
- /package/dist/{auto-sync-5OE5QOZB.js.map → auto-sync-UPTUVE4X.js.map} +0 -0
- /package/dist/{chunk-VUPTKTDV.js.map → chunk-2MRHJNWL.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-5IVLTFOV.js.map → chunk-44N6ESJ4.js.map} +0 -0
- /package/dist/{chunk-HO3QBJEY.js.map → chunk-5546W5SI.js.map} +0 -0
- /package/dist/{chunk-U7GW7NE7.js.map → chunk-5CEECY6P.js.map} +0 -0
- /package/dist/{chunk-4UH4BTGK.js.map → chunk-5SNZSWWR.js.map} +0 -0
- /package/dist/{chunk-6CZPDBJS.js.map → chunk-5U7ID3EZ.js.map} +0 -0
- /package/dist/{chunk-GF22HWS2.js.map → chunk-6NNNURLK.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-7RZJWZ46.js.map} +0 -0
- /package/dist/{chunk-E5UK4VPE.js.map → chunk-7SHJHPTY.js.map} +0 -0
- /package/dist/{chunk-UVIKWC7M.js.map → chunk-7YERSTN7.js.map} +0 -0
- /package/dist/{chunk-S5SLVSVY.js.map → chunk-BQIFZ2MP.js.map} +0 -0
- /package/dist/{chunk-E53DSZEN.js.map → chunk-C26TE27X.js.map} +0 -0
- /package/dist/{chunk-LZ4LDKHZ.js.map → chunk-CLB32OHM.js.map} +0 -0
- /package/dist/{chunk-Q6IP2ARR.js.map → chunk-CSOYVTRX.js.map} +0 -0
- /package/dist/{chunk-XOQSEF7X.js.map → chunk-CVILPI77.js.map} +0 -0
- /package/dist/{chunk-PDLBLTOK.js.map → chunk-EITZHSX6.js.map} +0 -0
- /package/dist/{chunk-WUNIWKY4.js.map → chunk-ELIL2A37.js.map} +0 -0
- /package/dist/{chunk-CINZGPSJ.js.map → chunk-GUMZC2BO.js.map} +0 -0
- /package/dist/{chunk-H24WNPA2.js.map → chunk-GWFSVJ4P.js.map} +0 -0
- /package/dist/{chunk-TSH56VPU.js.map → chunk-HAYSYUAB.js.map} +0 -0
- /package/dist/{chunk-PKNLM44P.js.map → chunk-JH6BPLOP.js.map} +0 -0
- /package/dist/{chunk-KXB4VXHY.js.map → chunk-JIYDRBVZ.js.map} +0 -0
- /package/dist/{chunk-AV5ZEH4M.js.map → chunk-KVJRXN2E.js.map} +0 -0
- /package/dist/{chunk-JVLCVFQ4.js.map → chunk-KXEFRMCF.js.map} +0 -0
- /package/dist/{chunk-WFTIGIIS.js.map → chunk-L6CQ7WIW.js.map} +0 -0
- /package/dist/{chunk-EJUEXZHX.js.map → chunk-LLJMAULE.js.map} +0 -0
- /package/dist/{chunk-AS7YMSL6.js.map → chunk-M23RF3LJ.js.map} +0 -0
- /package/dist/{chunk-3F2LKUMU.js.map → chunk-NIS256NW.js.map} +0 -0
- /package/dist/{chunk-YIAA2X3D.js.map → chunk-NK5RGJ65.js.map} +0 -0
- /package/dist/{chunk-OQ5PRDDS.js.map → chunk-NTOIP2E6.js.map} +0 -0
- /package/dist/{chunk-HLPD7B7P.js.map → chunk-NUEQKLNB.js.map} +0 -0
- /package/dist/{chunk-33PLLLL7.js.map → chunk-P7NGM24P.js.map} +0 -0
- /package/dist/{chunk-7TWUCYER.js.map → chunk-PNRA7FAD.js.map} +0 -0
- /package/dist/{chunk-5I4M26Q7.js.map → chunk-QBSFOKY6.js.map} +0 -0
- /package/dist/{chunk-P4DRWEYC.js.map → chunk-QVSBTCVP.js.map} +0 -0
- /package/dist/{chunk-AAIUERNB.js.map → chunk-R5RFK3CB.js.map} +0 -0
- /package/dist/{chunk-WDISJRMG.js.map → chunk-RMMVQQA6.js.map} +0 -0
- /package/dist/{chunk-5SM35XZR.js.map → chunk-S5NZBKKQ.js.map} +0 -0
- /package/dist/{chunk-WIPEXG6R.js.map → chunk-SXIMQLGV.js.map} +0 -0
- /package/dist/{chunk-OAEQLRCY.js.map → chunk-TN76AKO3.js.map} +0 -0
- /package/dist/{chunk-QN25OCUF.js.map → chunk-TQ4GD737.js.map} +0 -0
- /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-DNWXFTLD.js.map → chunk-TYISDI6B.js.map} +0 -0
- /package/dist/{chunk-4LMA77JH.js.map → chunk-U2VLVBBH.js.map} +0 -0
- /package/dist/{chunk-5ZE7QHTK.js.map → chunk-ULVR5KG7.js.map} +0 -0
- /package/dist/{chunk-4B77XSG5.js.map → chunk-UV72DEZD.js.map} +0 -0
- /package/dist/{chunk-S2BBISHU.js.map → chunk-VANZKHTN.js.map} +0 -0
- /package/dist/{chunk-3Y224NYC.js.map → chunk-VYISFWVX.js.map} +0 -0
- /package/dist/{chunk-TIHMZFIV.js.map → chunk-W3IC7QOY.js.map} +0 -0
- /package/dist/{chunk-NRV4Y3PM.js.map → chunk-W4FBGYGK.js.map} +0 -0
- /package/dist/{chunk-MU7ZHSZE.js.map → chunk-WZFAPHIK.js.map} +0 -0
- /package/dist/{chunk-T2TTP3KU.js.map → chunk-X4IDNPOS.js.map} +0 -0
- /package/dist/{chunk-BLAKS3CP.js.map → chunk-XL3TATMJ.js.map} +0 -0
- /package/dist/{chunk-W4XJFLAL.js.map → chunk-XPRJSHNI.js.map} +0 -0
- /package/dist/{chunk-JE7EK33X.js.map → chunk-Y7HRYCNW.js.map} +0 -0
- /package/dist/{chunk-E6EE5B67.js.map → chunk-YK6BDDHP.js.map} +0 -0
- /package/dist/{chunk-ES36HTSC.js.map → chunk-YLHM5BQQ.js.map} +0 -0
- /package/dist/{chunk-BJKPPZ6Z.js.map → chunk-ZFGZ6PZ2.js.map} +0 -0
- /package/dist/{chunk-64UDOIMI.js.map → chunk-ZLQ37WJX.js.map} +0 -0
package/src/storage.ts
CHANGED
|
@@ -4,15 +4,17 @@ import {
|
|
|
4
4
|
readdir,
|
|
5
5
|
readFile,
|
|
6
6
|
realpath,
|
|
7
|
+
rename,
|
|
7
8
|
stat,
|
|
8
9
|
writeFile,
|
|
9
10
|
mkdir,
|
|
10
11
|
unlink,
|
|
11
12
|
appendFile,
|
|
12
13
|
open,
|
|
14
|
+
type FileHandle,
|
|
13
15
|
} from "node:fs/promises";
|
|
14
16
|
import { appendFileSync, createReadStream, mkdirSync, readFileSync, statSync, type Dirent } from "node:fs";
|
|
15
|
-
import { createHash } from "node:crypto";
|
|
17
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
16
18
|
import { normalizeContent, computeContentHash } from "./content-hash.js";
|
|
17
19
|
import path from "node:path";
|
|
18
20
|
import { log } from "./logger.js";
|
|
@@ -45,10 +47,13 @@ import {
|
|
|
45
47
|
import { EntityCanonicalIdMigrationRunner } from "./storage/entity-canonical-id-migration-runner.js";
|
|
46
48
|
import { rememberRawFrontmatter } from "./storage/memory-frontmatter-metadata.js";
|
|
47
49
|
import { createMemoryEntityRefSerializer } from "./storage/memory-migration-serialization.js";
|
|
50
|
+
import { readEntityAliasConfigSync } from "./storage/entity-alias-config.js";
|
|
51
|
+
import { assertSafeEntityId } from "./storage/entity-id-safety.js";
|
|
48
52
|
export { normalizeEntityName } from "./entity-id-normalization.js";
|
|
49
53
|
import { isErrnoCode } from "./utils/errno.js";
|
|
50
54
|
import { getCategoryDir, categoryDirName } from "./utils/category-dir.js";
|
|
51
55
|
import { decodeYamlScalar } from "./utils/yaml-scalar.js";
|
|
56
|
+
import { withHeldFileLock, type HeldFileLockController } from "./utils/serialize-mutations.js";
|
|
52
57
|
import { qmdCollectionPathParts, qmdResultPathCandidates } from "./orchestration/qmd-result-resolver.js";
|
|
53
58
|
import {
|
|
54
59
|
clearMemoryCache,
|
|
@@ -72,6 +77,7 @@ import {
|
|
|
72
77
|
} from "./in-flight-reads.js";
|
|
73
78
|
import { rotateMarkdownFileToArchive } from "./hygiene.js";
|
|
74
79
|
import { sanitizeMemoryContent } from "./sanitize.js";
|
|
80
|
+
import { withholdToolScopedFromSharedNamespace } from "./tool-scoped-memory.js";
|
|
75
81
|
import {
|
|
76
82
|
serializeProvenanceFields,
|
|
77
83
|
parseProvenanceSources,
|
|
@@ -191,6 +197,11 @@ import {
|
|
|
191
197
|
parseTombstoneBlockedOfflineSyncMemory,
|
|
192
198
|
type TombstoneBlockedCaptureIndexOptions,
|
|
193
199
|
} from "./storage/tombstone-blocked-capture-index.js";
|
|
200
|
+
import {
|
|
201
|
+
buildCapturePathLockIdentity,
|
|
202
|
+
isQueuedReviewMemory,
|
|
203
|
+
tombstoneBlocked,
|
|
204
|
+
} from "./storage/tombstone-blocked-capture-mutation.js";
|
|
194
205
|
export { ContentHashIndex, FactHashIndexNotAuthoritativeError };
|
|
195
206
|
export type { ContentHashIndexLockOptions };
|
|
196
207
|
export {
|
|
@@ -264,6 +275,37 @@ type OfflineSyncDigestCacheEntry = {
|
|
|
264
275
|
bytes: number;
|
|
265
276
|
};
|
|
266
277
|
|
|
278
|
+
type DeletionRevisionMetadata = {
|
|
279
|
+
version: 1;
|
|
280
|
+
deletions: Array<{ path: string; mtimeMs: number }>;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const DELETION_REVISION_MAX_MTIME_MS = 8_640_000_000_000_000;
|
|
284
|
+
const DELETION_REVISION_LOCK_STALE_MS = 60_000;
|
|
285
|
+
const DELETION_REVISION_LOCK_MAX_WAIT_MS = 120_000;
|
|
286
|
+
|
|
287
|
+
function isValidDeletionRevisionPath(value: unknown): value is string {
|
|
288
|
+
return (
|
|
289
|
+
typeof value === "string" &&
|
|
290
|
+
value.length > 0 &&
|
|
291
|
+
!value.includes("\\") &&
|
|
292
|
+
!value.includes("\0") &&
|
|
293
|
+
!path.posix.isAbsolute(value) &&
|
|
294
|
+
path.posix.normalize(value) === value &&
|
|
295
|
+
value !== "." &&
|
|
296
|
+
value !== ".." &&
|
|
297
|
+
!value.startsWith("../")
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function deletionRevisionPathIdentity(value: string): string {
|
|
302
|
+
return value
|
|
303
|
+
.normalize("NFC")
|
|
304
|
+
.toUpperCase()
|
|
305
|
+
.toLowerCase()
|
|
306
|
+
.replace(/\u00df/g, "ss");
|
|
307
|
+
}
|
|
308
|
+
|
|
267
309
|
export interface ReextractJobRequest {
|
|
268
310
|
memoryId: string;
|
|
269
311
|
model: string;
|
|
@@ -343,6 +385,7 @@ function serializeFrontmatter(fm: MemoryFrontmatter): string {
|
|
|
343
385
|
const safe = /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(fm.sourceConnector);
|
|
344
386
|
lines.push(`sourceConnector: ${safe ? fm.sourceConnector : JSON.stringify(fm.sourceConnector)}`);
|
|
345
387
|
}
|
|
388
|
+
if (fm.toolScoped === true) lines.push("toolScoped: true");
|
|
346
389
|
if (fm.supersedes) lines.push(`supersedes: ${fm.supersedes}`);
|
|
347
390
|
if (fm.expiresAt) lines.push(`expiresAt: ${fm.expiresAt}`);
|
|
348
391
|
if (fm.lineage && fm.lineage.length > 0) {
|
|
@@ -609,7 +652,7 @@ function parseReinforcementCountField(raw: string | undefined): number | undefin
|
|
|
609
652
|
}
|
|
610
653
|
|
|
611
654
|
export function parseFrontmatter(raw: string): { frontmatter: MemoryFrontmatter; content: string } | null {
|
|
612
|
-
const match = raw.match(/^---\n([\s\S]*?)\n
|
|
655
|
+
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/);
|
|
613
656
|
if (!match) return null;
|
|
614
657
|
|
|
615
658
|
const fmBlock = match[1];
|
|
@@ -867,6 +910,7 @@ export function parseFrontmatter(raw: string): { frontmatter: MemoryFrontmatter;
|
|
|
867
910
|
tags,
|
|
868
911
|
entityRef: fm.entityRef || undefined,
|
|
869
912
|
sourceConnector: fm.sourceConnector ? decodeYamlScalar(fm.sourceConnector) || undefined : undefined,
|
|
913
|
+
toolScoped: fm.toolScoped === "true" ? true : undefined,
|
|
870
914
|
supersedes: fm.supersedes || undefined,
|
|
871
915
|
expiresAt: fm.expiresAt || undefined,
|
|
872
916
|
lineage: lineage && lineage.length > 0 ? lineage : undefined,
|
|
@@ -1024,7 +1068,6 @@ function inferCurrentStateStatus(
|
|
|
1024
1068
|
return inferMemoryStatus(frontmatter, pathRel, fallbackStatus);
|
|
1025
1069
|
}
|
|
1026
1070
|
|
|
1027
|
-
|
|
1028
1071
|
/**
|
|
1029
1072
|
* Simple Levenshtein distance between two strings.
|
|
1030
1073
|
*/
|
|
@@ -1720,6 +1763,7 @@ export interface WriteMemoryOptions {
|
|
|
1720
1763
|
sources?: ProvenanceSource[];
|
|
1721
1764
|
provenance?: "verified" | "unverified" | "none";
|
|
1722
1765
|
sourceConnector?: string;
|
|
1766
|
+
toolScoped?: true;
|
|
1723
1767
|
}
|
|
1724
1768
|
|
|
1725
1769
|
/**
|
|
@@ -2005,9 +2049,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
2005
2049
|
setSecureStoreKey(key: Buffer | null, encryptOnWrite = true): void {
|
|
2006
2050
|
if (!this.applySecureStoreKey(key, encryptOnWrite) || key === null) return;
|
|
2007
2051
|
void this.entityCanonicalIdMigration.triggerAfterUnlock().catch((error: unknown) => {
|
|
2008
|
-
log.warn(
|
|
2009
|
-
`secure-store unlock migration failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
2010
|
-
);
|
|
2052
|
+
log.warn(`secure-store unlock migration failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2011
2053
|
});
|
|
2012
2054
|
}
|
|
2013
2055
|
|
|
@@ -2316,10 +2358,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
2316
2358
|
return path.join(this.stateDir, `.${kind}-version.log`);
|
|
2317
2359
|
}
|
|
2318
2360
|
|
|
2319
|
-
private bumpSharedVersion(
|
|
2320
|
-
kind: SharedVersionKind,
|
|
2321
|
-
fallbackMap: Map<string, number>
|
|
2322
|
-
): number {
|
|
2361
|
+
private bumpSharedVersion(kind: SharedVersionKind, fallbackMap: Map<string, number>): number {
|
|
2323
2362
|
const filePath = this.versionFilePath(kind);
|
|
2324
2363
|
try {
|
|
2325
2364
|
mkdirSync(this.stateDir, { recursive: true });
|
|
@@ -2334,10 +2373,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
2334
2373
|
}
|
|
2335
2374
|
}
|
|
2336
2375
|
|
|
2337
|
-
private readSharedVersion(
|
|
2338
|
-
kind: SharedVersionKind,
|
|
2339
|
-
fallbackMap: Map<string, number>
|
|
2340
|
-
): number {
|
|
2376
|
+
private readSharedVersion(kind: SharedVersionKind, fallbackMap: Map<string, number>): number {
|
|
2341
2377
|
const filePath = this.versionFilePath(kind);
|
|
2342
2378
|
try {
|
|
2343
2379
|
return statSync(filePath).size;
|
|
@@ -2364,15 +2400,14 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
2364
2400
|
}
|
|
2365
2401
|
|
|
2366
2402
|
/**
|
|
2367
|
-
* Entity
|
|
2368
|
-
* The migration fingerprint keys on this instead of memory-status, so
|
|
2369
|
-
* supersede/archive/delete no longer re-trigger discovery scans (#2213).
|
|
2403
|
+
* Entity content revision used by migration discovery and entity-page cache coherence.
|
|
2370
2404
|
*/
|
|
2371
2405
|
getEntityMutationVersion(): number {
|
|
2372
2406
|
return this.readSharedVersion("entity-mutation", StorageManager.entityMutationVersionByDir);
|
|
2373
2407
|
}
|
|
2374
2408
|
|
|
2375
2409
|
protected bumpEntityMutationVersion(): void {
|
|
2410
|
+
invalidateForScope(this.baseDir, "entity-write");
|
|
2376
2411
|
this.bumpSharedVersion("entity-mutation", StorageManager.entityMutationVersionByDir);
|
|
2377
2412
|
}
|
|
2378
2413
|
|
|
@@ -2646,6 +2681,217 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
2646
2681
|
return resolved;
|
|
2647
2682
|
}
|
|
2648
2683
|
|
|
2684
|
+
private parseDeletionRevisionMetadata(raw: string): Map<string, number> {
|
|
2685
|
+
let parsed: unknown;
|
|
2686
|
+
try {
|
|
2687
|
+
parsed = JSON.parse(raw);
|
|
2688
|
+
} catch {
|
|
2689
|
+
throw new Error("Deletion revision metadata is invalid.");
|
|
2690
|
+
}
|
|
2691
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2692
|
+
throw new Error("Deletion revision metadata is invalid.");
|
|
2693
|
+
}
|
|
2694
|
+
const root = parsed as Record<string, unknown>;
|
|
2695
|
+
if (
|
|
2696
|
+
Object.keys(root).sort().join(",") !== "deletions,version" ||
|
|
2697
|
+
root.version !== 1 ||
|
|
2698
|
+
!Array.isArray(root.deletions)
|
|
2699
|
+
) {
|
|
2700
|
+
throw new Error("Deletion revision metadata is invalid.");
|
|
2701
|
+
}
|
|
2702
|
+
const revisions = new Map<string, number>();
|
|
2703
|
+
const pathByIdentity = new Map<string, string>();
|
|
2704
|
+
for (const rawEntry of root.deletions) {
|
|
2705
|
+
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) {
|
|
2706
|
+
throw new Error("Deletion revision metadata is invalid.");
|
|
2707
|
+
}
|
|
2708
|
+
const entry = rawEntry as Record<string, unknown>;
|
|
2709
|
+
if (
|
|
2710
|
+
Object.keys(entry).sort().join(",") !== "mtimeMs,path" ||
|
|
2711
|
+
!isValidDeletionRevisionPath(entry.path) ||
|
|
2712
|
+
typeof entry.mtimeMs !== "number" ||
|
|
2713
|
+
!Number.isFinite(entry.mtimeMs) ||
|
|
2714
|
+
entry.mtimeMs < 0 ||
|
|
2715
|
+
entry.mtimeMs > DELETION_REVISION_MAX_MTIME_MS ||
|
|
2716
|
+
revisions.has(entry.path)
|
|
2717
|
+
) {
|
|
2718
|
+
throw new Error("Deletion revision metadata is invalid.");
|
|
2719
|
+
}
|
|
2720
|
+
const identity = deletionRevisionPathIdentity(entry.path);
|
|
2721
|
+
if (pathByIdentity.has(identity)) {
|
|
2722
|
+
throw new Error("Deletion revision metadata is invalid.");
|
|
2723
|
+
}
|
|
2724
|
+
pathByIdentity.set(identity, entry.path);
|
|
2725
|
+
revisions.set(entry.path, entry.mtimeMs);
|
|
2726
|
+
}
|
|
2727
|
+
return new Map([...revisions.entries()].sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0)));
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
private async readDeletionRevisionMetadata(): Promise<Map<string, number>> {
|
|
2731
|
+
let raw: string;
|
|
2732
|
+
try {
|
|
2733
|
+
raw = await readFile(this.deletionRevisionMetadataPath, "utf8");
|
|
2734
|
+
} catch (error) {
|
|
2735
|
+
if (isErrnoCode(error, "ENOENT")) return new Map();
|
|
2736
|
+
throw new Error("Deletion revision metadata is unavailable.");
|
|
2737
|
+
}
|
|
2738
|
+
return this.parseDeletionRevisionMetadata(raw);
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
private async writeDeletionRevisionMetadata(
|
|
2742
|
+
revisions: ReadonlyMap<string, number>,
|
|
2743
|
+
lock: HeldFileLockController
|
|
2744
|
+
): Promise<void> {
|
|
2745
|
+
const deletions = [...revisions.entries()]
|
|
2746
|
+
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
2747
|
+
.map(([entryPath, mtimeMs]) => ({ path: entryPath, mtimeMs }));
|
|
2748
|
+
const metadata: DeletionRevisionMetadata = { version: 1, deletions };
|
|
2749
|
+
const temporaryPath = `${this.deletionRevisionMetadataPath}.${process.pid}.${randomUUID()}.tmp`;
|
|
2750
|
+
let handle: FileHandle | null = null;
|
|
2751
|
+
try {
|
|
2752
|
+
handle = await open(temporaryPath, "wx", 0o600);
|
|
2753
|
+
await handle.writeFile(`${JSON.stringify(metadata)}\n`, "utf8");
|
|
2754
|
+
await handle.sync();
|
|
2755
|
+
await handle.close();
|
|
2756
|
+
handle = null;
|
|
2757
|
+
if (!(await lock.refresh())) {
|
|
2758
|
+
throw new Error("Deletion revision metadata lock was lost.");
|
|
2759
|
+
}
|
|
2760
|
+
await rename(temporaryPath, this.deletionRevisionMetadataPath);
|
|
2761
|
+
} finally {
|
|
2762
|
+
if (handle !== null) await handle.close().catch(() => undefined);
|
|
2763
|
+
await unlink(temporaryPath).catch((error: unknown) => {
|
|
2764
|
+
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
2765
|
+
});
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
private async withDeletionRevisionLock<T>(task: (lock: HeldFileLockController) => Promise<T>): Promise<T> {
|
|
2770
|
+
return withHeldFileLock(
|
|
2771
|
+
this.deletionRevisionLockPath,
|
|
2772
|
+
{
|
|
2773
|
+
staleMs: DELETION_REVISION_LOCK_STALE_MS,
|
|
2774
|
+
maxWaitMs: DELETION_REVISION_LOCK_MAX_WAIT_MS,
|
|
2775
|
+
},
|
|
2776
|
+
async (acquired, lock) => {
|
|
2777
|
+
if (!acquired) throw new Error("Deletion revision metadata lock is unavailable.");
|
|
2778
|
+
return task(lock);
|
|
2779
|
+
}
|
|
2780
|
+
);
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
async readDeletionRevisions(): Promise<ReadonlyMap<string, number>> {
|
|
2784
|
+
return this.withDeletionRevisionLock(async () => this.readDeletionRevisionMetadata());
|
|
2785
|
+
}
|
|
2786
|
+
|
|
2787
|
+
async recordReplicatedDeletionRevision(filePath: string, mtimeMs: number): Promise<void> {
|
|
2788
|
+
const target = this.assertManagedStoragePath(filePath, "storage.recordReplicatedDeletionRevision");
|
|
2789
|
+
if (
|
|
2790
|
+
typeof mtimeMs !== "number" ||
|
|
2791
|
+
!Number.isFinite(mtimeMs) ||
|
|
2792
|
+
mtimeMs < 0 ||
|
|
2793
|
+
mtimeMs > DELETION_REVISION_MAX_MTIME_MS
|
|
2794
|
+
) {
|
|
2795
|
+
throw new Error("Deletion revision timestamp is invalid.");
|
|
2796
|
+
}
|
|
2797
|
+
const relativePath = path.relative(this.baseDir, target).split(path.sep).join("/");
|
|
2798
|
+
if (!isValidDeletionRevisionPath(relativePath)) {
|
|
2799
|
+
throw new Error("Deletion revision path is invalid.");
|
|
2800
|
+
}
|
|
2801
|
+
await this.withDeletionRevisionLock(async (lock) => {
|
|
2802
|
+
const revisions = await this.readDeletionRevisionMetadata();
|
|
2803
|
+
const identity = deletionRevisionPathIdentity(relativePath);
|
|
2804
|
+
let existingPath: string | undefined;
|
|
2805
|
+
for (const candidatePath of revisions.keys()) {
|
|
2806
|
+
if (deletionRevisionPathIdentity(candidatePath) === identity) {
|
|
2807
|
+
existingPath = candidatePath;
|
|
2808
|
+
break;
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
const existingMtimeMs = existingPath === undefined ? undefined : revisions.get(existingPath);
|
|
2812
|
+
if (existingMtimeMs !== undefined && existingMtimeMs >= mtimeMs) return;
|
|
2813
|
+
|
|
2814
|
+
const updated = new Map(revisions);
|
|
2815
|
+
if (existingPath !== undefined) updated.delete(existingPath);
|
|
2816
|
+
updated.set(relativePath, mtimeMs);
|
|
2817
|
+
await this.writeDeletionRevisionMetadata(updated, lock);
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
protected async writeManagedStorageFile(filePath: string, write: () => Promise<void>): Promise<void> {
|
|
2822
|
+
const target = this.assertManagedStoragePath(filePath, "storage.writeManagedStorageFile");
|
|
2823
|
+
const relativePath = path.relative(this.baseDir, target).split(path.sep).join("/");
|
|
2824
|
+
if (!isValidDeletionRevisionPath(relativePath)) {
|
|
2825
|
+
throw new Error("Deletion revision path is invalid.");
|
|
2826
|
+
}
|
|
2827
|
+
await this.withDeletionRevisionLock(async (lock) => {
|
|
2828
|
+
const before = await this.readDeletionRevisionMetadata();
|
|
2829
|
+
const identity = deletionRevisionPathIdentity(relativePath);
|
|
2830
|
+
const existingPath = [...before.keys()].find(
|
|
2831
|
+
(candidatePath) => deletionRevisionPathIdentity(candidatePath) === identity
|
|
2832
|
+
);
|
|
2833
|
+
await write();
|
|
2834
|
+
if (existingPath === undefined) return;
|
|
2835
|
+
const updated = new Map(before);
|
|
2836
|
+
updated.delete(existingPath);
|
|
2837
|
+
await this.writeDeletionRevisionMetadata(updated, lock);
|
|
2838
|
+
});
|
|
2839
|
+
}
|
|
2840
|
+
|
|
2841
|
+
protected async deleteManagedStorageFile(filePath: string, deletionMtimeMs?: number | null): Promise<boolean> {
|
|
2842
|
+
const target = this.assertManagedStoragePath(filePath, "storage.deleteManagedStorageFile");
|
|
2843
|
+
if (
|
|
2844
|
+
deletionMtimeMs !== undefined &&
|
|
2845
|
+
deletionMtimeMs !== null &&
|
|
2846
|
+
(typeof deletionMtimeMs !== "number" ||
|
|
2847
|
+
!Number.isFinite(deletionMtimeMs) ||
|
|
2848
|
+
deletionMtimeMs < 0 ||
|
|
2849
|
+
deletionMtimeMs > DELETION_REVISION_MAX_MTIME_MS)
|
|
2850
|
+
) {
|
|
2851
|
+
throw new Error("Deletion revision timestamp is invalid.");
|
|
2852
|
+
}
|
|
2853
|
+
return this.withDeletionRevisionLock(async (lock) => {
|
|
2854
|
+
try {
|
|
2855
|
+
await lstat(target);
|
|
2856
|
+
} catch (error) {
|
|
2857
|
+
if (isErrnoCode(error, "ENOENT")) return false;
|
|
2858
|
+
throw error;
|
|
2859
|
+
}
|
|
2860
|
+
const relativePath = path.relative(this.baseDir, target).split(path.sep).join("/");
|
|
2861
|
+
if (!isValidDeletionRevisionPath(relativePath)) {
|
|
2862
|
+
throw new Error("Deletion revision path is invalid.");
|
|
2863
|
+
}
|
|
2864
|
+
const revision = deletionMtimeMs === null ? undefined : (deletionMtimeMs ?? Date.now());
|
|
2865
|
+
const before = await this.readDeletionRevisionMetadata();
|
|
2866
|
+
const identity = deletionRevisionPathIdentity(relativePath);
|
|
2867
|
+
let existingPath: string | undefined;
|
|
2868
|
+
for (const candidatePath of before.keys()) {
|
|
2869
|
+
if (deletionRevisionPathIdentity(candidatePath) === identity) {
|
|
2870
|
+
existingPath = candidatePath;
|
|
2871
|
+
break;
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
const existing = existingPath === undefined ? undefined : before.get(existingPath);
|
|
2875
|
+
const changed =
|
|
2876
|
+
(existingPath !== undefined && existingPath !== relativePath) ||
|
|
2877
|
+
(revision === undefined ? existing !== undefined : existing !== revision);
|
|
2878
|
+
if (changed) {
|
|
2879
|
+
const updated = new Map(before);
|
|
2880
|
+
if (existingPath !== undefined) updated.delete(existingPath);
|
|
2881
|
+
if (revision !== undefined) updated.set(relativePath, revision);
|
|
2882
|
+
await this.writeDeletionRevisionMetadata(updated, lock);
|
|
2883
|
+
}
|
|
2884
|
+
try {
|
|
2885
|
+
await unlink(target);
|
|
2886
|
+
return true;
|
|
2887
|
+
} catch (error) {
|
|
2888
|
+
if (changed) await this.writeDeletionRevisionMetadata(before, lock);
|
|
2889
|
+
if (isErrnoCode(error, "ENOENT")) return false;
|
|
2890
|
+
throw error;
|
|
2891
|
+
}
|
|
2892
|
+
});
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2649
2895
|
async readOfflineSyncFile(filePath: string): Promise<Buffer> {
|
|
2650
2896
|
const target = this.assertManagedStoragePath(filePath, "storage.readOfflineSyncFile");
|
|
2651
2897
|
return readMaybeEncryptedFileBuffer(target, this._secureStoreKey, this.baseDir);
|
|
@@ -2929,6 +3175,12 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
2929
3175
|
private get offlineSyncDigestCachePath(): string {
|
|
2930
3176
|
return path.join(this.baseDir, ".offline-sync", "digest-cache.v1.json");
|
|
2931
3177
|
}
|
|
3178
|
+
private get deletionRevisionMetadataPath(): string {
|
|
3179
|
+
return path.join(this.baseDir, ".offline-sync", "deletion-revisions.v1.json");
|
|
3180
|
+
}
|
|
3181
|
+
private get deletionRevisionLockPath(): string {
|
|
3182
|
+
return `${this.deletionRevisionMetadataPath}.lock`;
|
|
3183
|
+
}
|
|
2932
3184
|
private get entitySynthesisQueuePath(): string {
|
|
2933
3185
|
return path.join(this.stateDir, "entity-synthesis-queue.json");
|
|
2934
3186
|
}
|
|
@@ -3062,7 +3314,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3062
3314
|
() => this.currentHistoricalIds(),
|
|
3063
3315
|
(identity) => store.appendTombstone({ ...input, rawContent: strippedRawContent, ...identity }),
|
|
3064
3316
|
(tombstoneId) => store.revoke(tombstoneId, input.createdBy),
|
|
3065
|
-
input.sourceMemoryId
|
|
3317
|
+
input.sourceMemoryId
|
|
3066
3318
|
);
|
|
3067
3319
|
} catch (err) {
|
|
3068
3320
|
log.warn(`tombstone append failed (memory=${input.sourceMemoryId}): ${err}`);
|
|
@@ -3455,12 +3707,12 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3455
3707
|
private readonly entityCanonicalIdMigration = new EntityCanonicalIdMigrationRunner(
|
|
3456
3708
|
() => !(this._secureStoreRequired && !this.isSecureStoreUnlocked()),
|
|
3457
3709
|
() => this.runLegacyEntityCanonicalIdMigration(),
|
|
3458
|
-
() => entityMigration.getFingerprint(this.baseDir, this.entitiesDir, () => String(this.getEntityMutationVersion()))
|
|
3710
|
+
() => entityMigration.getFingerprint(this.baseDir, this.entitiesDir, () => String(this.getEntityMutationVersion()))
|
|
3459
3711
|
);
|
|
3460
3712
|
normalizeEntityName(raw: string, type: string): string {
|
|
3461
3713
|
return entityRefs.resolveHistoricalEntityCanonicalId(
|
|
3462
3714
|
this.entityStore.normalizeEntityName(raw, type),
|
|
3463
|
-
this.currentHistoricalIds()
|
|
3715
|
+
this.currentHistoricalIds()
|
|
3464
3716
|
);
|
|
3465
3717
|
}
|
|
3466
3718
|
|
|
@@ -3485,27 +3737,28 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3485
3737
|
|
|
3486
3738
|
private loadAliasesSync(): void {
|
|
3487
3739
|
const aliasPath = path.join(this.baseDir, "config", "aliases.json");
|
|
3488
|
-
// Re-derive from the file on every call: a reload after the file was
|
|
3489
|
-
// fixed, emptied, or removed must never leave a previous table active.
|
|
3490
3740
|
this.userAliases = {};
|
|
3741
|
+
const raw = readEntityAliasConfigSync(this.baseDir);
|
|
3742
|
+
if (raw === undefined) return;
|
|
3743
|
+
let parsed: unknown;
|
|
3491
3744
|
try {
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3745
|
+
parsed = JSON.parse(raw);
|
|
3746
|
+
} catch {
|
|
3747
|
+
log.debug("invalid config/aliases.json — using built-in aliases only");
|
|
3748
|
+
return;
|
|
3749
|
+
}
|
|
3750
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
3751
|
+
const cleaned: Record<string, string> = {};
|
|
3752
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
3753
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
3754
|
+
assertSafeEntityId(value);
|
|
3755
|
+
cleaned[key] = value;
|
|
3500
3756
|
}
|
|
3501
|
-
this.userAliases = cleaned;
|
|
3502
|
-
log.debug(`loaded ${Object.keys(cleaned).length} entity aliases from ${aliasPath}`);
|
|
3503
|
-
} else {
|
|
3504
|
-
log.warn(`ignoring ${aliasPath}: payload must be a JSON object mapping variant → canonical strings`);
|
|
3505
3757
|
}
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3758
|
+
this.userAliases = cleaned;
|
|
3759
|
+
log.debug(`loaded ${Object.keys(cleaned).length} entity aliases from ${aliasPath}`);
|
|
3760
|
+
} else {
|
|
3761
|
+
log.warn(`ignoring ${aliasPath}: payload must be a JSON object mapping variant → canonical strings`);
|
|
3509
3762
|
}
|
|
3510
3763
|
}
|
|
3511
3764
|
private async runLegacyEntityCanonicalIdMigration(): Promise<string | undefined> {
|
|
@@ -3513,7 +3766,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3513
3766
|
this as unknown as EntityCanonicalIdMigrationHost,
|
|
3514
3767
|
(content) => parseEntityFile(content, this.entitySchemas),
|
|
3515
3768
|
(entity) => serializeEntityFile(entity, this.entitySchemas),
|
|
3516
|
-
createMemoryEntityRefSerializer(serializeFrontmatter)
|
|
3769
|
+
createMemoryEntityRefSerializer(serializeFrontmatter)
|
|
3517
3770
|
);
|
|
3518
3771
|
return completionFingerprint;
|
|
3519
3772
|
}
|
|
@@ -3690,6 +3943,15 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3690
3943
|
if (!sanitized.clean) {
|
|
3691
3944
|
log.warn(`memory content sanitized for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
3692
3945
|
}
|
|
3946
|
+
if (
|
|
3947
|
+
options.toolScoped ||
|
|
3948
|
+
withholdToolScopedFromSharedNamespace({
|
|
3949
|
+
content: sanitized.text,
|
|
3950
|
+
sourceConnector: options.sourceConnector,
|
|
3951
|
+
})
|
|
3952
|
+
) {
|
|
3953
|
+
fm.toolScoped = true;
|
|
3954
|
+
}
|
|
3693
3955
|
|
|
3694
3956
|
// Persist the raw-content dedup hash on the frontmatter so archive and
|
|
3695
3957
|
// consolidation paths can remove the correct hash from ContentHashIndex
|
|
@@ -3754,14 +4016,41 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3754
4016
|
await this.writeTombstoneBlockedMemory(filePath, fileContent, fm, sanitized.text, async () => {
|
|
3755
4017
|
this.invalidateAllMemoriesCache();
|
|
3756
4018
|
});
|
|
4019
|
+
if (refIds && typeof rawEntityRef === "string") {
|
|
4020
|
+
const refBeforeRepair = fm.entityRef;
|
|
4021
|
+
try {
|
|
4022
|
+
await entityRefs.repairEntityRefAfterJournalMove({
|
|
4023
|
+
stateDir: this.stateDir,
|
|
4024
|
+
currentIds: () => this.currentHistoricalIds(),
|
|
4025
|
+
idsAtResolve: refIds,
|
|
4026
|
+
rawRef: rawEntityRef,
|
|
4027
|
+
frontmatter: fm,
|
|
4028
|
+
rewrite: async () => {
|
|
4029
|
+
await applyTombstoneGate();
|
|
4030
|
+
await this.writeTombstoneBlockedMemory(
|
|
4031
|
+
filePath,
|
|
4032
|
+
`${serializeFrontmatter(fm)}\n\n${sanitized.text}\n`,
|
|
4033
|
+
fm,
|
|
4034
|
+
sanitized.text,
|
|
4035
|
+
async () => this.invalidateAllMemoriesCache()
|
|
4036
|
+
);
|
|
4037
|
+
this.invalidateAllMemoriesCache();
|
|
4038
|
+
},
|
|
4039
|
+
});
|
|
4040
|
+
} catch (err) {
|
|
4041
|
+
await unlink(filePath).catch(() => undefined);
|
|
4042
|
+
this.invalidateAllMemoriesCache();
|
|
4043
|
+
await this.rebuildTombstoneBlockedCaptureAfterInvalidationForPath(filePath);
|
|
4044
|
+
throw err;
|
|
4045
|
+
}
|
|
4046
|
+
await this.entityRefRepair.syncProjection(id, refBeforeRepair, fm.entityRef);
|
|
4047
|
+
}
|
|
3757
4048
|
return null;
|
|
3758
4049
|
};
|
|
3759
|
-
const duplicateBlocked =
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
)
|
|
3764
|
-
: await persistFile();
|
|
4050
|
+
const duplicateBlocked = await this.withTombstoneBlockedCaptureWriteLock(persistFile, [
|
|
4051
|
+
buildCapturePathLockIdentity(filePath),
|
|
4052
|
+
buildExplicitCaptureDedupKey(sanitized.text, category, fm.sourceConnector),
|
|
4053
|
+
]);
|
|
3765
4054
|
if (duplicateBlocked) {
|
|
3766
4055
|
return {
|
|
3767
4056
|
id: duplicateBlocked.frontmatter.id,
|
|
@@ -3770,38 +4059,6 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3770
4059
|
duplicateOf: duplicateBlocked.frontmatter.id,
|
|
3771
4060
|
};
|
|
3772
4061
|
}
|
|
3773
|
-
if (refIds && typeof rawEntityRef === "string") {
|
|
3774
|
-
const refBeforeRepair = fm.entityRef;
|
|
3775
|
-
try {
|
|
3776
|
-
await entityRefs.repairEntityRefAfterJournalMove({
|
|
3777
|
-
stateDir: this.stateDir,
|
|
3778
|
-
currentIds: () => this.currentHistoricalIds(),
|
|
3779
|
-
idsAtResolve: refIds,
|
|
3780
|
-
rawRef: rawEntityRef,
|
|
3781
|
-
frontmatter: fm,
|
|
3782
|
-
rewrite: async () => {
|
|
3783
|
-
// Re-gate under the final ref, then rewrite THROUGH the blocked-
|
|
3784
|
-
// capture surface so any verdict change keeps the index consistent.
|
|
3785
|
-
await applyTombstoneGate();
|
|
3786
|
-
await this.writeTombstoneBlockedMemory(
|
|
3787
|
-
filePath,
|
|
3788
|
-
`${serializeFrontmatter(fm)}\n\n${sanitized.text}\n`,
|
|
3789
|
-
fm,
|
|
3790
|
-
sanitized.text,
|
|
3791
|
-
async () => this.invalidateAllMemoriesCache(),
|
|
3792
|
-
);
|
|
3793
|
-
this.invalidateAllMemoriesCache();
|
|
3794
|
-
},
|
|
3795
|
-
});
|
|
3796
|
-
} catch (err) {
|
|
3797
|
-
// Remove the just-created file before propagating (§14): it would
|
|
3798
|
-
// linger un-bumped/un-indexed and a retry would duplicate it.
|
|
3799
|
-
await unlink(filePath).catch(() => undefined);
|
|
3800
|
-
this.invalidateAllMemoriesCache();
|
|
3801
|
-
throw err;
|
|
3802
|
-
}
|
|
3803
|
-
await this.entityRefRepair.syncProjection(id, refBeforeRepair, fm.entityRef);
|
|
3804
|
-
}
|
|
3805
4062
|
await this.patchHotMemoriesCache({ addedPath: filePath }, "memory-create");
|
|
3806
4063
|
this.notifyMemoryWrite(filePath);
|
|
3807
4064
|
await this.appendGeneratedMemoryLifecycleEventFailOpen("storage.writeMemory", {
|
|
@@ -4073,6 +4330,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4073
4330
|
intentActionType?: string;
|
|
4074
4331
|
intentEntityTypes?: string[];
|
|
4075
4332
|
sourceConnector?: string;
|
|
4333
|
+
toolScoped?: true;
|
|
4076
4334
|
} = {}
|
|
4077
4335
|
): Promise<string> {
|
|
4078
4336
|
await this.ensureDirectories();
|
|
@@ -4098,6 +4356,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4098
4356
|
intentActionType: options.intentActionType,
|
|
4099
4357
|
intentEntityTypes: options.intentEntityTypes,
|
|
4100
4358
|
...(options.sourceConnector ? { sourceConnector: options.sourceConnector } : {}),
|
|
4359
|
+
...(options.toolScoped ? { toolScoped: true as const } : {}),
|
|
4101
4360
|
};
|
|
4102
4361
|
|
|
4103
4362
|
const sanitized = sanitizeMemoryContent(quote);
|
|
@@ -4227,16 +4486,10 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4227
4486
|
if (newBullets.length === 0) return;
|
|
4228
4487
|
|
|
4229
4488
|
if (!existing) {
|
|
4230
|
-
const content = [
|
|
4231
|
-
"# Behavioral Profile",
|
|
4232
|
-
"",
|
|
4233
|
-
...newBullets.map((b) => `- ${b}`),
|
|
4234
|
-
"",
|
|
4235
|
-
].join("\n");
|
|
4489
|
+
const content = ["# Behavioral Profile", "", ...newBullets.map((b) => `- ${b}`), ""].join("\n");
|
|
4236
4490
|
await this.writeProfile(content);
|
|
4237
4491
|
} else {
|
|
4238
|
-
const withBullets =
|
|
4239
|
-
existing.trimEnd() + "\n" + newBullets.map((b) => `- ${b}`).join("\n") + "\n";
|
|
4492
|
+
const withBullets = existing.trimEnd() + "\n" + newBullets.map((b) => `- ${b}`).join("\n") + "\n";
|
|
4240
4493
|
await this.writeProfile(withBullets);
|
|
4241
4494
|
}
|
|
4242
4495
|
}
|
|
@@ -4601,15 +4854,18 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4601
4854
|
const raw = await readMaybeEncryptedFile(fullPath, this._secureStoreKey, this.baseDir);
|
|
4602
4855
|
const parsed = parseFrontmatter(raw);
|
|
4603
4856
|
if (!parsed) return null;
|
|
4604
|
-
return rememberRawFrontmatter(
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4857
|
+
return rememberRawFrontmatter(
|
|
4858
|
+
{
|
|
4859
|
+
path: fullPath,
|
|
4860
|
+
frontmatter: normalizeFrontmatterForPath(
|
|
4861
|
+
parsed.frontmatter,
|
|
4862
|
+
toMemoryPathRel(this.baseDir, fullPath),
|
|
4863
|
+
parsed.content
|
|
4864
|
+
),
|
|
4865
|
+
content: parsed.content,
|
|
4866
|
+
} satisfies MemoryFile,
|
|
4867
|
+
raw
|
|
4868
|
+
);
|
|
4613
4869
|
} catch (err) {
|
|
4614
4870
|
// Re-throw store-locked errors so a locked encrypted store fails
|
|
4615
4871
|
// loudly rather than appearing as an empty memory corpus (Cursor
|
|
@@ -4760,15 +5016,20 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4760
5016
|
const raw = await readMaybeEncryptedFile(fullPath, this._secureStoreKey, this.baseDir);
|
|
4761
5017
|
const parsed = parseFrontmatter(raw);
|
|
4762
5018
|
if (parsed) {
|
|
4763
|
-
memories.push(
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
5019
|
+
memories.push(
|
|
5020
|
+
rememberRawFrontmatter(
|
|
5021
|
+
{
|
|
5022
|
+
path: fullPath,
|
|
5023
|
+
frontmatter: normalizeFrontmatterForPath(
|
|
5024
|
+
parsed.frontmatter,
|
|
5025
|
+
toMemoryPathRel(this.baseDir, fullPath),
|
|
5026
|
+
parsed.content
|
|
5027
|
+
),
|
|
5028
|
+
content: parsed.content,
|
|
5029
|
+
},
|
|
5030
|
+
raw
|
|
5031
|
+
)
|
|
5032
|
+
);
|
|
4772
5033
|
}
|
|
4773
5034
|
} catch (err) {
|
|
4774
5035
|
// Re-throw store-locked errors — a locked encrypted store
|
|
@@ -4838,7 +5099,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4838
5099
|
`${serializeFrontmatter(frontmatter)}\n\n${memory.content}\n`,
|
|
4839
5100
|
this.resolveWriteKey(),
|
|
4840
5101
|
{},
|
|
4841
|
-
this.baseDir
|
|
5102
|
+
this.baseDir
|
|
4842
5103
|
);
|
|
4843
5104
|
// Snapshot pre-write destination bytes (raw — encryption-agnostic) so a
|
|
4844
5105
|
// repair failure restores them or removes a fresh copy (§14): a retained
|
|
@@ -4877,24 +5138,51 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4877
5138
|
this.notifyCatalogWrite();
|
|
4878
5139
|
}
|
|
4879
5140
|
async moveMemoryToPath(memory: MemoryFile, targetPath: string): Promise<void> {
|
|
4880
|
-
await this.
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
await unlink(memory.path);
|
|
4886
|
-
} catch (err) {
|
|
4887
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
4888
|
-
if (!message.includes("ENOENT")) {
|
|
4889
|
-
throw err;
|
|
5141
|
+
await this.withTombstoneBlockedMemoryPathLock(
|
|
5142
|
+
memory.path,
|
|
5143
|
+
async (current) => {
|
|
5144
|
+
if (current?.frontmatter.id !== memory.frontmatter.id) {
|
|
5145
|
+
throw new Error(`memory ${memory.frontmatter.id} changed before its tier move`);
|
|
4890
5146
|
}
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
5147
|
+
const destination = await this.readMemoryByPath(targetPath);
|
|
5148
|
+
const coordinate =
|
|
5149
|
+
tombstoneBlocked(current.frontmatter) ||
|
|
5150
|
+
isQueuedReviewMemory(current) ||
|
|
5151
|
+
(destination !== null && tombstoneBlocked(destination.frontmatter)) ||
|
|
5152
|
+
isQueuedReviewMemory(destination);
|
|
5153
|
+
const index = this.getTombstoneBlockedCaptureIndex();
|
|
5154
|
+
const marker = coordinate ? await index.prepareWrite() : undefined;
|
|
5155
|
+
let durable = false;
|
|
5156
|
+
try {
|
|
5157
|
+
if (destination?.frontmatter.id === current.frontmatter.id) {
|
|
5158
|
+
await this.deleteManagedStorageFile(current.path);
|
|
5159
|
+
durable = true;
|
|
5160
|
+
this.invalidateAllMemoriesCache();
|
|
5161
|
+
updateProjectedMemoryPath(this.baseDir, current.frontmatter.id, toMemoryPathRel(this.baseDir, targetPath));
|
|
5162
|
+
} else {
|
|
5163
|
+
await this.writeMemoryFileAtomic(targetPath, current);
|
|
5164
|
+
durable = true;
|
|
5165
|
+
const sourcePath = path.resolve(current.path);
|
|
5166
|
+
const destPath = path.resolve(targetPath);
|
|
5167
|
+
if (sourcePath !== destPath) {
|
|
5168
|
+
await this.deleteManagedStorageFile(current.path);
|
|
5169
|
+
this.invalidateAllMemoriesCache();
|
|
5170
|
+
updateProjectedMemoryPath(
|
|
5171
|
+
this.baseDir,
|
|
5172
|
+
current.frontmatter.id,
|
|
5173
|
+
toMemoryPathRel(this.baseDir, targetPath)
|
|
5174
|
+
);
|
|
5175
|
+
}
|
|
5176
|
+
}
|
|
5177
|
+
if (marker !== undefined) await this.rebuildTombstoneBlockedCaptureAfterInvalidation(marker);
|
|
5178
|
+
} catch (error) {
|
|
5179
|
+
if (marker !== undefined && !durable) await index.discardWrite(marker).catch(() => index.markUntrusted());
|
|
5180
|
+
if (marker !== undefined && durable) index.markUntrusted();
|
|
5181
|
+
throw error;
|
|
5182
|
+
}
|
|
5183
|
+
},
|
|
5184
|
+
[targetPath]
|
|
5185
|
+
);
|
|
4898
5186
|
}
|
|
4899
5187
|
|
|
4900
5188
|
async migrateMemoryToTier(
|
|
@@ -4908,21 +5196,6 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4908
5196
|
return { changed: false, targetPath };
|
|
4909
5197
|
}
|
|
4910
5198
|
|
|
4911
|
-
const existing = await this.readMemoryByPath(targetPath);
|
|
4912
|
-
if (existing?.frontmatter.id === memory.frontmatter.id) {
|
|
4913
|
-
try {
|
|
4914
|
-
await unlink(memory.path);
|
|
4915
|
-
} catch (err) {
|
|
4916
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
4917
|
-
if (!message.includes("ENOENT")) {
|
|
4918
|
-
throw err;
|
|
4919
|
-
}
|
|
4920
|
-
}
|
|
4921
|
-
updateProjectedMemoryPath(this.baseDir, memory.frontmatter.id, toMemoryPathRel(this.baseDir, targetPath));
|
|
4922
|
-
this.bumpMemoryStatusVersion();
|
|
4923
|
-
return { changed: false, targetPath };
|
|
4924
|
-
}
|
|
4925
|
-
|
|
4926
5199
|
await this.moveMemoryToPath(memory, targetPath);
|
|
4927
5200
|
this.invalidateAllMemoriesCache();
|
|
4928
5201
|
// If moving to cold, also invalidate the cold-scan cache so the next
|
|
@@ -4959,7 +5232,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4959
5232
|
archivedAt: now.toISOString(),
|
|
4960
5233
|
updated: now.toISOString(),
|
|
4961
5234
|
},
|
|
4962
|
-
refIdsAtWrite
|
|
5235
|
+
refIdsAtWrite
|
|
4963
5236
|
);
|
|
4964
5237
|
const fileContent = `${serializeFrontmatter(updatedFm)}\n\n${current.content}\n`;
|
|
4965
5238
|
const destPath = path.join(destDir, path.basename(current.path));
|
|
@@ -4970,7 +5243,11 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4970
5243
|
if (typeof current.frontmatter.entityRef === "string") {
|
|
4971
5244
|
try {
|
|
4972
5245
|
await this.entityRefRepair.repair(
|
|
4973
|
-
destPath,
|
|
5246
|
+
destPath,
|
|
5247
|
+
updatedFm,
|
|
5248
|
+
current.frontmatter.entityRef,
|
|
5249
|
+
refIdsAtWrite,
|
|
5250
|
+
current.content
|
|
4974
5251
|
);
|
|
4975
5252
|
} catch (err) {
|
|
4976
5253
|
// Restore/remove the destination before reporting failure (§14):
|
|
@@ -4983,7 +5260,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
4983
5260
|
throw err;
|
|
4984
5261
|
}
|
|
4985
5262
|
}
|
|
4986
|
-
await
|
|
5263
|
+
if (!(await this.deleteManagedStorageFile(current.path))) return null;
|
|
4987
5264
|
markDurable();
|
|
4988
5265
|
markProjectedMemoryPathInvalid(this.baseDir, current.frontmatter.id);
|
|
4989
5266
|
this.invalidateAllMemoriesCache();
|
|
@@ -5076,25 +5353,21 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
5076
5353
|
return null;
|
|
5077
5354
|
}
|
|
5078
5355
|
|
|
5079
|
-
|
|
5080
5356
|
async invalidateMemory(id: string): Promise<boolean> {
|
|
5081
5357
|
const memories = await this.readAllMemories();
|
|
5082
5358
|
const memory = memories.find((candidate) => candidate.frontmatter.id === id);
|
|
5083
5359
|
if (!memory) return false;
|
|
5084
5360
|
|
|
5085
|
-
return await this.runTombstoneBlockedInvalidation(
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
return true;
|
|
5096
|
-
}
|
|
5097
|
-
);
|
|
5361
|
+
return await this.runTombstoneBlockedInvalidation(memory, async (current, rebuildMarker, markDurable) => {
|
|
5362
|
+
if (!(await this.deleteManagedStorageFile(current.path))) return false;
|
|
5363
|
+
markDurable();
|
|
5364
|
+
markProjectedMemoryPathInvalid(this.baseDir, id);
|
|
5365
|
+
this.invalidateAllMemoriesCache();
|
|
5366
|
+
await this.rebuildTombstoneBlockedCaptureAfterInvalidation(rebuildMarker);
|
|
5367
|
+
this.bumpMemoryStatusVersion();
|
|
5368
|
+
log.debug(`invalidated memory ${id}`);
|
|
5369
|
+
return true;
|
|
5370
|
+
});
|
|
5098
5371
|
}
|
|
5099
5372
|
|
|
5100
5373
|
async updateMemory(
|
|
@@ -5122,7 +5395,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
5122
5395
|
? { sourceConnector: options.sourceConnector }
|
|
5123
5396
|
: {}),
|
|
5124
5397
|
},
|
|
5125
|
-
refIdsAtWrite
|
|
5398
|
+
refIdsAtWrite
|
|
5126
5399
|
);
|
|
5127
5400
|
const sanitized = sanitizeMemoryContent(newContent);
|
|
5128
5401
|
if (!sanitized.clean) {
|
|
@@ -5134,8 +5407,12 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
5134
5407
|
});
|
|
5135
5408
|
if (typeof memory.frontmatter.entityRef === "string") {
|
|
5136
5409
|
await this.entityRefRepair.repair(
|
|
5137
|
-
memory.path,
|
|
5138
|
-
|
|
5410
|
+
memory.path,
|
|
5411
|
+
updated,
|
|
5412
|
+
memory.frontmatter.entityRef,
|
|
5413
|
+
refIdsAtWrite,
|
|
5414
|
+
sanitized.text,
|
|
5415
|
+
{ onFailRestore: memory }
|
|
5139
5416
|
);
|
|
5140
5417
|
}
|
|
5141
5418
|
await this.patchHotMemoriesCache({ addedPath: memory.path });
|
|
@@ -5170,7 +5447,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
5170
5447
|
const resolveIds = this.currentHistoricalIds();
|
|
5171
5448
|
const updated: MemoryFrontmatter = entityRefs.canonicalizeEntityRefOption(
|
|
5172
5449
|
{ ...memory.frontmatter, ...patch },
|
|
5173
|
-
resolveIds
|
|
5450
|
+
resolveIds
|
|
5174
5451
|
);
|
|
5175
5452
|
const refIds = typeof updated.entityRef === "string" ? resolveIds : null;
|
|
5176
5453
|
const afterStatus = updated.status ?? "active";
|
|
@@ -5185,10 +5462,9 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
5185
5462
|
});
|
|
5186
5463
|
const rawMergedRef = typeof patch.entityRef === "string" ? patch.entityRef : memory.frontmatter.entityRef;
|
|
5187
5464
|
if (refIds && typeof rawMergedRef === "string") {
|
|
5188
|
-
await this.entityRefRepair.repair(
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
);
|
|
5465
|
+
await this.entityRefRepair.repair(memory.path, updated, rawMergedRef, refIds, memory.content, {
|
|
5466
|
+
onFailRestore: memory,
|
|
5467
|
+
});
|
|
5192
5468
|
}
|
|
5193
5469
|
await this.patchHotMemoriesCache({ addedPath: memory.path });
|
|
5194
5470
|
if (memory.path.includes(`${path.sep}cold${path.sep}`)) {
|
|
@@ -6336,26 +6612,31 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6336
6612
|
: memoryMap.get(entry.memoryId);
|
|
6337
6613
|
if (!memory) continue;
|
|
6338
6614
|
|
|
6339
|
-
const rowIds = this.currentHistoricalIds();
|
|
6340
|
-
const newFm: MemoryFrontmatter = entityRefs.canonicalizeEntityRefOption(
|
|
6341
|
-
{ ...memory.frontmatter, accessCount: entry.newCount, lastAccessed: entry.lastAccessed },
|
|
6342
|
-
rowIds,
|
|
6343
|
-
);
|
|
6344
|
-
|
|
6345
6615
|
try {
|
|
6346
|
-
const
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
{ onFailRestore: memory },
|
|
6616
|
+
const applied = await this.withTombstoneBlockedMemoryPathLock(memory.path, async (current) => {
|
|
6617
|
+
if (current?.frontmatter.id !== entry.memoryId) return null;
|
|
6618
|
+
const rowIds = this.currentHistoricalIds();
|
|
6619
|
+
const newFm: MemoryFrontmatter = entityRefs.canonicalizeEntityRefOption(
|
|
6620
|
+
{ ...current.frontmatter, accessCount: entry.newCount, lastAccessed: entry.lastAccessed },
|
|
6621
|
+
rowIds
|
|
6353
6622
|
);
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6623
|
+
const fileContent = `${serializeFrontmatter(newFm)}\n\n${current.content}\n`;
|
|
6624
|
+
await this.writeTombstoneBlockedFrontmatter(current, fileContent, newFm);
|
|
6625
|
+
if (typeof current.frontmatter.entityRef === "string") {
|
|
6626
|
+
await this.entityRefRepair.repair(
|
|
6627
|
+
current.path,
|
|
6628
|
+
newFm,
|
|
6629
|
+
current.frontmatter.entityRef,
|
|
6630
|
+
rowIds,
|
|
6631
|
+
current.content,
|
|
6632
|
+
{ onFailRestore: current }
|
|
6633
|
+
);
|
|
6634
|
+
}
|
|
6635
|
+
return { current, newFm };
|
|
6636
|
+
});
|
|
6637
|
+
if (applied === null) continue;
|
|
6357
6638
|
if (warm) {
|
|
6358
|
-
updateCacheOnWrite(this.baseDir, { ...
|
|
6639
|
+
updateCacheOnWrite(this.baseDir, { ...applied.current, frontmatter: applied.newFm }, keyId);
|
|
6359
6640
|
}
|
|
6360
6641
|
appliedPatches.set(path.resolve(memory.path), {
|
|
6361
6642
|
accessCount: entry.newCount,
|
|
@@ -6602,6 +6883,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6602
6883
|
observedAt?: string;
|
|
6603
6884
|
eventTimeSource?: "extracted" | "assumed";
|
|
6604
6885
|
sourceConnector?: string;
|
|
6886
|
+
toolScoped?: true;
|
|
6605
6887
|
} = {}
|
|
6606
6888
|
): Promise<string> {
|
|
6607
6889
|
await this.ensureDirectories();
|
|
@@ -6616,6 +6898,10 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6616
6898
|
const validAt = normalizeMemoryWriteTimestamp("validAt", options.validAt);
|
|
6617
6899
|
const chunkInvalidAt = normalizeMemoryWriteTimestamp("invalidAt", options.invalidAt);
|
|
6618
6900
|
const chunkObservedAt = normalizeMemoryWriteTimestamp("observedAt", options.observedAt);
|
|
6901
|
+
const sanitized = sanitizeMemoryContent(content);
|
|
6902
|
+
if (!sanitized.clean) {
|
|
6903
|
+
log.warn(`chunk content sanitized for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
6904
|
+
}
|
|
6619
6905
|
|
|
6620
6906
|
const fm: MemoryFrontmatter = {
|
|
6621
6907
|
id,
|
|
@@ -6645,28 +6931,17 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6645
6931
|
...(options.sources ? { sources: options.sources } : {}),
|
|
6646
6932
|
...(options.provenance ? { provenance: options.provenance } : {}),
|
|
6647
6933
|
...(options.sourceConnector ? { sourceConnector: options.sourceConnector } : {}),
|
|
6934
|
+
...(options.toolScoped ||
|
|
6935
|
+
withholdToolScopedFromSharedNamespace({
|
|
6936
|
+
content: sanitized.text,
|
|
6937
|
+
sourceConnector: options.sourceConnector,
|
|
6938
|
+
})
|
|
6939
|
+
? { toolScoped: true as const }
|
|
6940
|
+
: {}),
|
|
6648
6941
|
};
|
|
6649
6942
|
|
|
6650
|
-
const sanitized = sanitizeMemoryContent(content);
|
|
6651
|
-
if (!sanitized.clean) {
|
|
6652
|
-
log.warn(`chunk content sanitized for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
6653
|
-
}
|
|
6654
6943
|
const filePath = await this.resolveCategoryWritePath(category, id, today);
|
|
6655
6944
|
const fileContent = `${serializeFrontmatter(fm)}\n\n${sanitized.text}\n`;
|
|
6656
|
-
// A retried chunk write lands on the SAME deterministic path, so the
|
|
6657
|
-
// target can already hold a valid prior chunk: snapshot it, and a repair
|
|
6658
|
-
// failure restores it — unlink only a file THIS invocation created
|
|
6659
|
-
// (Codex P2, round 22).
|
|
6660
|
-
let priorChunk: MemoryFile | null = null;
|
|
6661
|
-
try {
|
|
6662
|
-
const priorRaw = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
6663
|
-
const parsedPrior = parseFrontmatter(priorRaw);
|
|
6664
|
-
if (parsedPrior) {
|
|
6665
|
-
priorChunk = { path: filePath, frontmatter: parsedPrior.frontmatter, content: parsedPrior.content };
|
|
6666
|
-
}
|
|
6667
|
-
} catch {
|
|
6668
|
-
priorChunk = null;
|
|
6669
|
-
}
|
|
6670
6945
|
|
|
6671
6946
|
const written = await this.writeTombstoneBlockedChunk(
|
|
6672
6947
|
filePath,
|
|
@@ -6674,24 +6949,19 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6674
6949
|
fm,
|
|
6675
6950
|
sanitized.text,
|
|
6676
6951
|
() => this.findExistingTombstoneBlockedMemory(sanitized.text, category, fm.sourceConnector),
|
|
6677
|
-
async () => {
|
|
6952
|
+
async (priorChunk) => {
|
|
6953
|
+
if (refIds && typeof rawEntityRef === "string") {
|
|
6954
|
+
await this.entityRefRepair.repair(filePath, fm, rawEntityRef, refIds, sanitized.text, {
|
|
6955
|
+
regateFact: true,
|
|
6956
|
+
...(priorChunk ? { onFailRestore: priorChunk } : { onFailRemove: filePath }),
|
|
6957
|
+
});
|
|
6958
|
+
}
|
|
6678
6959
|
// Keep the version-keyed hot-memories cache coherent with the new chunk
|
|
6679
6960
|
// file (issue #1902) — same single-file patch path writeMemory uses.
|
|
6680
6961
|
await this.patchHotMemoriesCache({ addedPath: filePath }, "memory-create");
|
|
6681
6962
|
log.debug(`wrote chunk ${id} (${chunkIndex + 1}/${chunkTotal}) to ${filePath}`);
|
|
6682
6963
|
}
|
|
6683
6964
|
);
|
|
6684
|
-
// Repair only when THIS chunk persisted: a tombstone-dedupe result
|
|
6685
|
-
// returns an existing id without writing filePath, and an unconditional
|
|
6686
|
-
// repair rewrite would create a stray second chunk from scratch. The
|
|
6687
|
-
// rewrite RE-GATES under the final ref (Bugbot): a journal move into
|
|
6688
|
-
// tombstone-blocked identity space must not leave a fact chunk active.
|
|
6689
|
-
if (written === id && refIds && typeof rawEntityRef === "string") {
|
|
6690
|
-
await this.entityRefRepair.repair(filePath, fm, rawEntityRef, refIds, sanitized.text, {
|
|
6691
|
-
regateFact: true,
|
|
6692
|
-
...(priorChunk ? { onFailRestore: priorChunk } : { onFailRemove: filePath }),
|
|
6693
|
-
});
|
|
6694
|
-
}
|
|
6695
6965
|
return written;
|
|
6696
6966
|
}
|
|
6697
6967
|
|
|
@@ -6720,25 +6990,33 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6720
6990
|
if (!oldMemory) return false;
|
|
6721
6991
|
|
|
6722
6992
|
const now = new Date().toISOString();
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
const updatedFm: MemoryFrontmatter = entityRefs.canonicalizeEntityRefOption(
|
|
6726
|
-
{ ...oldMemory.frontmatter, status: "superseded", supersededBy: newMemoryId, supersededAt: now, updated: now },
|
|
6727
|
-
refIdsAtWrite,
|
|
6728
|
-
);
|
|
6729
|
-
|
|
6730
|
-
const fileContent = `${serializeFrontmatter(updatedFm)}\n\n${oldMemory.content}\n`;
|
|
6993
|
+
let currentBefore = oldMemory;
|
|
6994
|
+
let updatedFm = oldMemory.frontmatter;
|
|
6731
6995
|
|
|
6732
6996
|
try {
|
|
6733
|
-
await this.
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6997
|
+
const written = await this.withTombstoneBlockedMemoryPathLock(oldMemory.path, async (current) => {
|
|
6998
|
+
if (current?.frontmatter.id !== oldMemoryId) return false;
|
|
6999
|
+
currentBefore = current;
|
|
7000
|
+
const refIdsAtWrite = this.currentHistoricalIds();
|
|
7001
|
+
updatedFm = entityRefs.canonicalizeEntityRefOption(
|
|
7002
|
+
{ ...current.frontmatter, status: "superseded", supersededBy: newMemoryId, supersededAt: now, updated: now },
|
|
7003
|
+
refIdsAtWrite
|
|
6740
7004
|
);
|
|
6741
|
-
|
|
7005
|
+
const fileContent = `${serializeFrontmatter(updatedFm)}\n\n${current.content}\n`;
|
|
7006
|
+
await this.writeTombstoneBlockedFrontmatter(current, fileContent, updatedFm);
|
|
7007
|
+
if (typeof current.frontmatter.entityRef === "string") {
|
|
7008
|
+
await this.entityRefRepair.repair(
|
|
7009
|
+
current.path,
|
|
7010
|
+
updatedFm,
|
|
7011
|
+
current.frontmatter.entityRef,
|
|
7012
|
+
refIdsAtWrite,
|
|
7013
|
+
current.content,
|
|
7014
|
+
{ onFailRestore: current }
|
|
7015
|
+
);
|
|
7016
|
+
}
|
|
7017
|
+
return true;
|
|
7018
|
+
});
|
|
7019
|
+
if (!written) return false;
|
|
6742
7020
|
// Advance the corpus sentinel immediately after the on-disk write, BEFORE
|
|
6743
7021
|
// the awaited lifecycle append (Cursor Medium, #1902). Otherwise a warm
|
|
6744
7022
|
// hot-memories cache keeps serving the pre-supersede snapshot during the
|
|
@@ -6751,8 +7029,8 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6751
7029
|
timestamp: now,
|
|
6752
7030
|
actor: "storage.supersedeMemory",
|
|
6753
7031
|
reasonCode: reason,
|
|
6754
|
-
before: this.summarizeLifecycleState(
|
|
6755
|
-
after: this.summarizeLifecycleState(updatedFm,
|
|
7032
|
+
before: this.summarizeLifecycleState(currentBefore.frontmatter, currentBefore.path),
|
|
7033
|
+
after: this.summarizeLifecycleState(updatedFm, currentBefore.path),
|
|
6756
7034
|
relatedMemoryIds: [newMemoryId],
|
|
6757
7035
|
});
|
|
6758
7036
|
this.bumpMemoryStatusVersion();
|
|
@@ -6762,14 +7040,14 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6762
7040
|
// so emitting covers each exactly once (rule 22); facts only. One
|
|
6763
7041
|
// tombstone PER derived supersession key (thread Oci-Y) so a
|
|
6764
7042
|
// paraphrased re-write is caught on the keyed tier.
|
|
6765
|
-
if (
|
|
7043
|
+
if (currentBefore.frontmatter.category === "fact") {
|
|
6766
7044
|
for (const input of buildRetiredFactTombstoneInputs(
|
|
6767
7045
|
{
|
|
6768
7046
|
id: oldMemoryId,
|
|
6769
|
-
content: stripCitationForTemplate(
|
|
6770
|
-
contentHash:
|
|
7047
|
+
content: stripCitationForTemplate(currentBefore.content, this.citationTemplate),
|
|
7048
|
+
contentHash: currentBefore.frontmatter.contentHash,
|
|
6771
7049
|
entityRef: updatedFm.entityRef,
|
|
6772
|
-
structuredAttributes:
|
|
7050
|
+
structuredAttributes: currentBefore.frontmatter.structuredAttributes,
|
|
6773
7051
|
},
|
|
6774
7052
|
{
|
|
6775
7053
|
reason: "contradiction_resolution",
|
|
@@ -6783,7 +7061,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6783
7061
|
}
|
|
6784
7062
|
|
|
6785
7063
|
// Audit-trail correction — sealed even INSIDE the engine (#2022 review).
|
|
6786
|
-
const auditBody = `Superseded: ${
|
|
7064
|
+
const auditBody = `Superseded: ${currentBefore.content}\n\nReason: ${reason}`;
|
|
6787
7065
|
const auditInput = {
|
|
6788
7066
|
content: auditBody,
|
|
6789
7067
|
category: "correction" as const,
|
|
@@ -6854,22 +7132,33 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6854
7132
|
if (!memory) continue;
|
|
6855
7133
|
|
|
6856
7134
|
const now = new Date().toISOString();
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
{ ...memory.frontmatter, status: "archived", archivedAt: now, updated: now },
|
|
6860
|
-
rowIds,
|
|
6861
|
-
);
|
|
7135
|
+
let currentBefore = memory;
|
|
7136
|
+
let updatedFm = memory.frontmatter;
|
|
6862
7137
|
|
|
6863
7138
|
try {
|
|
6864
|
-
const
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
7139
|
+
const written = await this.withTombstoneBlockedMemoryPathLock(memory.path, async (current) => {
|
|
7140
|
+
if (current?.frontmatter.id !== id) return false;
|
|
7141
|
+
currentBefore = current;
|
|
7142
|
+
const rowIds = this.currentHistoricalIds();
|
|
7143
|
+
updatedFm = entityRefs.canonicalizeEntityRefOption(
|
|
7144
|
+
{ ...current.frontmatter, status: "archived", archivedAt: now, updated: now },
|
|
7145
|
+
rowIds
|
|
6871
7146
|
);
|
|
6872
|
-
|
|
7147
|
+
const fileContent = `${serializeFrontmatter(updatedFm)}\n\n${current.content}\n`;
|
|
7148
|
+
await this.writeTombstoneBlockedFrontmatter(current, fileContent, updatedFm);
|
|
7149
|
+
if (typeof current.frontmatter.entityRef === "string") {
|
|
7150
|
+
await this.entityRefRepair.repair(
|
|
7151
|
+
current.path,
|
|
7152
|
+
updatedFm,
|
|
7153
|
+
current.frontmatter.entityRef,
|
|
7154
|
+
rowIds,
|
|
7155
|
+
current.content,
|
|
7156
|
+
{ onFailRestore: current }
|
|
7157
|
+
);
|
|
7158
|
+
}
|
|
7159
|
+
return true;
|
|
7160
|
+
});
|
|
7161
|
+
if (!written) continue;
|
|
6873
7162
|
// Per-file corpus bump BEFORE the awaited lifecycle append (#1902):
|
|
6874
7163
|
// the end-of-loop status bump fires only after the whole batch.
|
|
6875
7164
|
this.bumpMemoryCorpusVersion();
|
|
@@ -6879,8 +7168,8 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6879
7168
|
timestamp: updatedFm.archivedAt ?? updatedFm.updated,
|
|
6880
7169
|
actor: "storage.archiveMemories",
|
|
6881
7170
|
reasonCode: `summary:${summaryId}`,
|
|
6882
|
-
before: this.summarizeLifecycleState(
|
|
6883
|
-
after: this.summarizeLifecycleState(updatedFm,
|
|
7171
|
+
before: this.summarizeLifecycleState(currentBefore.frontmatter, currentBefore.path),
|
|
7172
|
+
after: this.summarizeLifecycleState(updatedFm, currentBefore.path),
|
|
6884
7173
|
relatedMemoryIds: [summaryId],
|
|
6885
7174
|
});
|
|
6886
7175
|
archived++;
|