@remnic/core 10.0.48 → 10.0.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.js +73 -70
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.js +74 -71
- package/dist/access-boundary.js +73 -70
- package/dist/access-cli.js +170 -167
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.js +73 -70
- package/dist/access-http-briefing.d.ts +2 -0
- package/dist/access-http-briefing.d.ts.map +1 -1
- package/dist/access-http-briefing.js +74 -71
- package/dist/access-http-query.js +75 -72
- package/dist/access-http.d.ts.map +1 -1
- package/dist/access-http.js +96 -93
- package/dist/access-identity-continuity-surface.js +73 -70
- package/dist/access-lcm-surface.js +73 -70
- package/dist/access-mcp.js +85 -82
- package/dist/access-namespace-preflight.js +73 -70
- package/dist/access-observe-write-category.d.ts +1 -1
- package/dist/access-observe-write-category.d.ts.map +1 -1
- package/dist/access-observe-write-category.js +15 -14
- package/dist/access-observe-write-surface.d.ts.map +1 -1
- package/dist/access-observe-write-surface.js +73 -70
- package/dist/access-offline-manifest.js +9 -8
- package/dist/access-operations-batch.js +76 -73
- package/dist/access-operations.js +83 -80
- package/dist/access-recall-concurrency.js +73 -70
- package/dist/access-recall-response.js +73 -70
- package/dist/access-recall-surface.js +73 -70
- package/dist/access-schema.js +11 -10
- package/dist/access-service.d.ts +5 -0
- package/dist/access-service.d.ts.map +1 -1
- package/dist/access-service.js +73 -70
- package/dist/access-surface-catalog.js +75 -72
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/active-recall.js +32 -30
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/{auto-sync-BNCBMU6H.js → auto-sync-UQQ6YJSB.js} +3 -3
- package/dist/briefing-deadline.d.ts +7 -0
- package/dist/briefing-deadline.d.ts.map +1 -0
- package/dist/briefing-deadline.js +13 -0
- package/dist/briefing-window.d.ts +12 -4
- package/dist/briefing-window.d.ts.map +1 -1
- package/dist/briefing-window.js +3 -1
- package/dist/briefing.d.ts +2 -0
- package/dist/briefing.d.ts.map +1 -1
- package/dist/briefing.js +22 -20
- package/dist/buffer.js +6 -6
- package/dist/calibration.js +2 -2
- package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{capsule-merge-RNQUP2VL.js → capsule-merge-D4BTIJGK.js} +3 -3
- package/dist/capture-write-lock-scope.d.ts +7 -0
- package/dist/capture-write-lock-scope.d.ts.map +1 -0
- package/dist/capture-write-lock-scope.js +10 -0
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +23 -22
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.js +3 -3
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-FAKRTS3Y.js → chunk-2AKIVSHP.js} +2 -2
- package/dist/{chunk-EIYJK7OD.js → chunk-2M36PR7R.js} +2 -2
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-6P6MZDBL.js → chunk-3NL4ALUP.js} +2 -2
- package/dist/{chunk-6CC2YCKG.js → chunk-43TUWQNR.js} +3 -3
- package/dist/{chunk-H7BZBSP6.js → chunk-52II7PB6.js} +4 -4
- package/dist/{chunk-2NLCDNGA.js → chunk-564YP3DW.js} +2 -2
- package/dist/{chunk-5KGYR5VN.js → chunk-5DVOBBTV.js} +2 -2
- package/dist/{chunk-RT2GN6KQ.js → chunk-5FUDSK6Z.js} +2 -2
- package/dist/{chunk-B4XSXFKI.js → chunk-5G53JSRO.js} +2 -2
- package/dist/{chunk-BGK3SFCC.js → chunk-5X2H3X4J.js} +2 -2
- package/dist/{chunk-OXSTKCYK.js → chunk-6AEKSOWV.js} +33 -5
- package/dist/chunk-6AEKSOWV.js.map +1 -0
- package/dist/{chunk-4J7BNL7B.js → chunk-6ZQX3R66.js} +2 -2
- package/dist/{chunk-JNLYHJG7.js → chunk-74AY3S7U.js} +4 -4
- package/dist/{chunk-RUAIO5UA.js → chunk-7J6A5MV2.js} +2 -2
- package/dist/{chunk-A45QXZMU.js → chunk-7SAE6T36.js} +2 -2
- package/dist/chunk-7VLBZKNB.js +26 -0
- package/dist/chunk-7VLBZKNB.js.map +1 -0
- package/dist/{chunk-QE2XQM3S.js → chunk-7YVER7ZO.js} +2 -2
- package/dist/{chunk-IJH6METJ.js → chunk-A3UFV4K3.js} +4 -4
- package/dist/{chunk-LWRIGKFM.js → chunk-A5L5KGDI.js} +19 -1
- package/dist/chunk-A5L5KGDI.js.map +1 -0
- package/dist/{chunk-LXN737FX.js → chunk-AAANTXCQ.js} +2 -2
- package/dist/{chunk-I3IPXGFQ.js → chunk-AJJPXUE6.js} +4 -4
- package/dist/{chunk-2DPJFJFH.js → chunk-BNJAVRNJ.js} +11 -11
- package/dist/{chunk-YL564QS2.js → chunk-CCL2OXFO.js} +3 -3
- package/dist/{chunk-CHSRA76M.js → chunk-CRN3EPE2.js} +4 -3
- package/dist/chunk-CRN3EPE2.js.map +1 -0
- package/dist/{chunk-ZX5N5D6M.js → chunk-DAOMWGO2.js} +4 -4
- package/dist/{chunk-YUE7J2HZ.js → chunk-DMKTOCC7.js} +2 -2
- package/dist/chunk-DMKTOCC7.js.map +1 -0
- package/dist/{chunk-FRXS6SC7.js → chunk-EKUI7I2X.js} +20 -4
- package/dist/chunk-EKUI7I2X.js.map +1 -0
- package/dist/{chunk-PKPOO6X5.js → chunk-EKYWZYZJ.js} +25 -17
- package/dist/chunk-EKYWZYZJ.js.map +1 -0
- package/dist/{chunk-23ZMQONL.js → chunk-ERMT5WQM.js} +2 -2
- package/dist/{chunk-VTCNVGM6.js → chunk-EWBXMGXR.js} +2 -2
- package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
- package/dist/{chunk-XTN54NML.js → chunk-G3T6YMBO.js} +4 -4
- package/dist/{chunk-2JNBPOZ2.js → chunk-GDYLZ6FR.js} +3 -3
- package/dist/{chunk-DZPTR2XQ.js → chunk-GFAEKSFR.js} +2 -2
- package/dist/{chunk-L46MG2GE.js → chunk-GQIYL7OD.js} +400 -301
- package/dist/chunk-GQIYL7OD.js.map +1 -0
- package/dist/{chunk-M7LA4QBY.js → chunk-GXVXBYRA.js} +3 -3
- package/dist/{chunk-UXAF4RQM.js → chunk-HKOMHP6D.js} +27 -15
- package/dist/chunk-HKOMHP6D.js.map +1 -0
- package/dist/{chunk-JGMJZBFV.js → chunk-HPNXS6W6.js} +2 -2
- package/dist/{chunk-BFPF5N3H.js → chunk-HXFIILGF.js} +4 -4
- package/dist/{chunk-YBKQAVPZ.js → chunk-IMKOJVD4.js} +101 -81
- package/dist/chunk-IMKOJVD4.js.map +1 -0
- package/dist/{chunk-CMNL3QSL.js → chunk-IN6U2BS5.js} +2 -2
- package/dist/{chunk-BWRX322G.js → chunk-IUYXCTA7.js} +2 -2
- package/dist/{chunk-LU57EEJW.js → chunk-JBWD3J5U.js} +3 -3
- package/dist/chunk-JNA7LFMQ.js +41 -0
- package/dist/chunk-JNA7LFMQ.js.map +1 -0
- package/dist/{chunk-2V664H6O.js → chunk-JS44PBCM.js} +5 -5
- package/dist/{chunk-XKTHJHSQ.js → chunk-JZCBMKR5.js} +3 -3
- package/dist/{chunk-MXPVNDGO.js → chunk-K5QQXVG6.js} +12 -12
- package/dist/{chunk-BUKK5SWA.js → chunk-KQAFEZQX.js} +2 -2
- package/dist/{chunk-WUBGMV3G.js → chunk-KRAMCBIW.js} +9 -9
- package/dist/{chunk-NDMPRT3Z.js → chunk-KW5YZELC.js} +2 -2
- package/dist/{chunk-2RQR4TXV.js → chunk-LIBVANOF.js} +2 -2
- package/dist/{chunk-M7L5A2AT.js → chunk-LMMBV7QC.js} +4 -4
- package/dist/{chunk-PJBYVJKO.js → chunk-LXXIV7Y2.js} +2 -2
- package/dist/{chunk-MZCTS3ZG.js → chunk-M2DOJBH7.js} +2 -2
- package/dist/{chunk-WOPZ2P5Z.js → chunk-M4HRYLOA.js} +2 -2
- package/dist/{chunk-JCYEDMOY.js → chunk-M6TP6UYD.js} +3 -3
- package/dist/{chunk-KAUCVTAW.js → chunk-MLNXATFG.js} +2 -2
- package/dist/{chunk-2NX7JTST.js → chunk-MPWOAIIH.js} +2 -2
- package/dist/{chunk-RQLTCHUL.js → chunk-MWURUSRE.js} +13 -13
- package/dist/{chunk-3EGL7XZO.js → chunk-N74WJ7B2.js} +2 -2
- package/dist/{chunk-DRXTMDAG.js → chunk-N7FNCE7F.js} +2 -2
- package/dist/{chunk-6CWAY4R7.js → chunk-NPLM7AFU.js} +2 -2
- package/dist/{chunk-VECRSYQG.js → chunk-NRGQ5HJO.js} +1 -1
- package/dist/{chunk-PPDNG7WC.js → chunk-NSP5PIQH.js} +2 -2
- package/dist/{chunk-6HVLHIAB.js → chunk-P7OVFGMU.js} +2 -2
- package/dist/{chunk-EX27VKU6.js → chunk-PDTNQLPC.js} +2 -2
- package/dist/{chunk-ME5LVISI.js → chunk-PJCVI44H.js} +2 -2
- package/dist/{chunk-LJCHDFLP.js → chunk-Q3PNQYAC.js} +2 -2
- package/dist/{chunk-YFJHFEET.js → chunk-QS765SBL.js} +2 -2
- package/dist/{chunk-FJ264QBP.js → chunk-QTDZ2NYC.js} +11 -11
- package/dist/{chunk-Q6UZREJK.js → chunk-RKRX4C4H.js} +2 -2
- package/dist/{chunk-YFXRLRKP.js → chunk-S4OZKPBS.js} +7 -11
- package/dist/{chunk-YFXRLRKP.js.map → chunk-S4OZKPBS.js.map} +1 -1
- package/dist/{chunk-GLZWOIU3.js → chunk-SJTSWG2Z.js} +3 -3
- package/dist/{chunk-Y57GJDG5.js → chunk-SWRRZNHM.js} +14 -17
- package/dist/chunk-SWRRZNHM.js.map +1 -0
- package/dist/{chunk-CCTLRRV6.js → chunk-TEH5MDX5.js} +55 -34
- package/dist/chunk-TEH5MDX5.js.map +1 -0
- package/dist/{chunk-XM747YJF.js → chunk-TFWJXWL6.js} +2 -2
- package/dist/{chunk-QFQ4UG3I.js → chunk-TXKQBQYW.js} +4 -4
- package/dist/{chunk-BMOJFGVX.js → chunk-UALXWWGN.js} +2 -2
- package/dist/{chunk-B44NFHWI.js → chunk-UNOAVHV4.js} +2 -2
- package/dist/{chunk-TF5NZGPS.js → chunk-UQBOPCDK.js} +2 -2
- package/dist/{chunk-SUKPM6DV.js → chunk-UWMZT2TY.js} +47 -4
- package/dist/chunk-UWMZT2TY.js.map +1 -0
- package/dist/{chunk-5R2IF2KI.js → chunk-UXGXJUZ5.js} +7 -7
- package/dist/{chunk-FWV2SXSL.js → chunk-UZVQFGAY.js} +101 -98
- package/dist/chunk-UZVQFGAY.js.map +1 -0
- package/dist/{chunk-J6B6FK2X.js → chunk-VCOMACR6.js} +53 -53
- package/dist/{chunk-WCGJK4NQ.js → chunk-VKQI47DJ.js} +7 -7
- package/dist/{chunk-MPJDQC4G.js → chunk-WJCXUE2J.js} +2 -2
- package/dist/{chunk-BCDECPVO.js → chunk-WV4UYDP6.js} +2 -2
- package/dist/{chunk-VWJ56T63.js → chunk-WXJC2L66.js} +2 -2
- package/dist/chunk-X2KO4FK5.js +40 -0
- package/dist/chunk-X2KO4FK5.js.map +1 -0
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-FPANDKMQ.js → chunk-XC3H7KON.js} +2 -2
- package/dist/{chunk-OOOX5C4X.js → chunk-XL2EE5W3.js} +4 -4
- package/dist/{chunk-3DKKZVXS.js → chunk-XTXWR6KQ.js} +26 -11
- package/dist/chunk-XTXWR6KQ.js.map +1 -0
- package/dist/{chunk-3SL52JKD.js → chunk-XVZA6VXC.js} +4 -4
- package/dist/{chunk-CZVNOTLR.js → chunk-XXR4A33N.js} +2 -2
- package/dist/{chunk-2AV2U2SZ.js → chunk-YDIOMDBW.js} +2 -2
- package/dist/{chunk-XTVH2NAW.js → chunk-YECEEJUU.js} +3 -3
- package/dist/{chunk-QR6W3FSW.js → chunk-Z5277JWF.js} +3 -3
- package/dist/{chunk-CTHYR4QK.js → chunk-ZFNXJEUG.js} +2 -2
- package/dist/{chunk-6Q56WDHG.js → chunk-ZLCBLDJO.js} +2 -2
- package/dist/{chunk-VY6BD5KB.js → chunk-ZMO2S5RT.js} +12 -10
- package/dist/chunk-ZMO2S5RT.js.map +1 -0
- package/dist/{chunk-KRACAE73.js → chunk-ZNRTHYYW.js} +6 -6
- package/dist/{chunk-7AIPWNM7.js → chunk-ZSMA67FV.js} +2 -2
- package/dist/cli.js +123 -120
- package/dist/coding/export-okf-codegraph.js +19 -18
- package/dist/coding/export-okf-codegraph.js.map +1 -1
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.js +21 -20
- package/dist/config.js +32 -30
- package/dist/connectors/codex-materialize-runner.js +20 -19
- package/dist/connectors/index.js +20 -19
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.js +2 -2
- package/dist/convergence-refresh.js +22 -21
- package/dist/corpus-watermark.js +22 -21
- package/dist/correction/passive-correction-notifications.d.ts +1 -1
- package/dist/correction/passive-correction-notifications.d.ts.map +1 -1
- package/dist/dashboard-runtime.js +2 -2
- package/dist/deep-recall-http-glue.js +12 -11
- package/dist/deep-recall.js +2 -2
- package/dist/embedding-fallback.js +3 -2
- package/dist/embedding-generation-marker.d.ts +16 -0
- package/dist/embedding-generation-marker.d.ts.map +1 -0
- package/dist/embedding-generation-marker.js +19 -0
- package/dist/embedding-generation-marker.js.map +1 -0
- package/dist/embedding-index-storage.d.ts +2 -4
- package/dist/embedding-index-storage.d.ts.map +1 -1
- package/dist/embedding-index-storage.js +2 -1
- package/dist/{entity-canonical-id-migration-2YOLMOFC.js → entity-canonical-id-migration-ZBNRGUNV.js} +3 -3
- package/dist/entity-canonical-id-migration-ZBNRGUNV.js.map +1 -0
- package/dist/entity-retrieval.js +22 -21
- package/dist/event-order-recall.js +2 -2
- package/dist/explicit-capture.js +3 -3
- package/dist/external-wiki-access.js +74 -71
- package/dist/extraction-span-materialize.js +2 -2
- package/dist/extraction.js +30 -29
- package/dist/{graph-edge-decay-3HVLMT6U.js → graph-edge-decay-IU75NV42.js} +6 -6
- package/dist/graph-edge-decay-IU75NV42.js.map +1 -0
- package/dist/graph-jsonl.js +4 -4
- package/dist/graph-snapshot.js +4 -4
- package/dist/graph.js +5 -5
- package/dist/harmonic-retrieval.js +20 -19
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +230 -218
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.js +5 -5
- package/dist/local-llm.js +2 -2
- package/dist/location/index.js +25 -24
- package/dist/location/tagging.d.ts +7 -5
- package/dist/location/tagging.d.ts.map +1 -1
- package/dist/maintenance/memory-governance.js +20 -19
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +20 -19
- package/dist/maintenance/rebuild-memory-projection-runner.js +22 -21
- package/dist/maintenance/rebuild-memory-projection.js +21 -20
- package/dist/memory-browse-operations.js +74 -71
- package/dist/memory-browse.js +5 -5
- package/dist/namespaces/migrate.js +21 -20
- package/dist/namespaces/search.js +6 -6
- package/dist/namespaces/storage.js +20 -19
- package/dist/offline-sync-changeset-generations.js +5 -4
- package/dist/offline-sync-embedding-generation.d.ts +12 -2
- package/dist/offline-sync-embedding-generation.d.ts.map +1 -1
- package/dist/offline-sync-embedding-generation.js +6 -3
- package/dist/offline-sync-file-io.d.ts +15 -0
- package/dist/offline-sync-file-io.d.ts.map +1 -1
- package/dist/offline-sync-file-io.js +9 -1
- package/dist/offline-sync-snapshot-stream.js +9 -8
- package/dist/offline-sync-upload-staging.js +2 -2
- package/dist/offline-sync.d.ts.map +1 -1
- package/dist/offline-sync.js +10 -9
- package/dist/operator-doctor-corpus.js +23 -22
- package/dist/operator-toolkit.js +45 -43
- package/dist/orchestration/maintenance.js +33 -32
- package/dist/orchestrator.d.ts +1 -0
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +170 -167
- package/dist/page-versioning.js +2 -2
- package/dist/qmd.js +2 -2
- package/dist/recall-navigation-operations.js +74 -71
- package/dist/recall-navigation.js +73 -70
- package/dist/recall-state-view-admission.js +5 -5
- package/dist/recall-why-service.js +5 -5
- package/dist/resume-bundles.js +33 -31
- package/dist/search/factory.js +5 -5
- package/dist/search/index.js +9 -9
- package/dist/semantic-consolidation.js +25 -24
- package/dist/semantic-rule-promotion.js +20 -19
- package/dist/semantic-rule-verifier.js +20 -19
- package/dist/source-agent-qualifier.js +24 -23
- package/dist/standup/build.js +20 -19
- package/dist/storage/entity-canonical-id-migration-adapter.d.ts +1 -0
- package/dist/storage/entity-canonical-id-migration-adapter.d.ts.map +1 -1
- package/dist/storage/entity-canonical-id-migration.d.ts +7 -0
- package/dist/storage/entity-canonical-id-migration.d.ts.map +1 -1
- package/dist/storage/entity-canonical-id-references.d.ts +2 -0
- package/dist/storage/entity-canonical-id-references.d.ts.map +1 -1
- package/dist/storage/entity-migration-completion-cache.d.ts +46 -0
- package/dist/storage/entity-migration-completion-cache.d.ts.map +1 -0
- package/dist/storage/entity-store.d.ts +1 -8
- package/dist/storage/entity-store.d.ts.map +1 -1
- package/dist/storage/memory-read-store.d.ts +3 -2
- package/dist/storage/memory-read-store.d.ts.map +1 -1
- package/dist/storage/windowed-memory-read.d.ts +6 -0
- package/dist/storage/windowed-memory-read.d.ts.map +1 -1
- package/dist/storage.d.ts +2 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +19 -18
- package/dist/summarizer.js +3 -3
- package/dist/support-passport/index.js +76 -73
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/transfer/export-okf.js +20 -19
- package/dist/verified-recall.js +20 -19
- package/dist/who-knows-cli.js +21 -20
- package/dist/who-knows.js +20 -19
- package/package.json +2 -2
- package/src/access-http-briefing.ts +4 -0
- package/src/access-http.test.ts +40 -11
- package/src/access-http.ts +6 -0
- package/src/access-observe-write-category.ts +1 -1
- package/src/access-observe-write-surface.ts +24 -19
- package/src/access-operations-batch.ts +18 -2
- package/src/access-service-peer-capture-backoff.test.ts +236 -0
- package/src/access-service.ts +11 -2
- package/src/briefing-abort.test.ts +173 -0
- package/src/briefing-deadline.test.ts +84 -0
- package/src/briefing-deadline.ts +33 -0
- package/src/briefing-window-abort.test.ts +47 -0
- package/src/briefing-window.ts +33 -4
- package/src/briefing.ts +23 -16
- package/src/capture-write-lock-scope.test.ts +32 -0
- package/src/capture-write-lock-scope.ts +30 -0
- package/src/correction/passive-correction-notifications-abort.test.ts +42 -0
- package/src/correction/passive-correction-notifications.ts +4 -0
- package/src/embedding-generation-marker.ts +51 -0
- package/src/embedding-index-storage.ts +13 -29
- package/src/entity-lazy-compatibility.test.ts +229 -0
- package/src/entity-migration-completion-notification.test.ts +148 -0
- package/src/index.ts +2 -2
- package/src/location/tagging.ts +14 -12
- package/src/offline-sync-embedding-delete-digest.test.ts +58 -0
- package/src/offline-sync-embedding-generation-marker.test.ts +245 -0
- package/src/offline-sync-embedding-generation.ts +47 -2
- package/src/offline-sync-embedding-lock-loss.test.ts +42 -0
- package/src/offline-sync-file-io.ts +61 -2
- package/src/offline-sync.test.ts +313 -20
- package/src/offline-sync.ts +47 -22
- package/src/orchestrator-init.test.ts +49 -1
- package/src/orchestrator.ts +9 -8
- package/src/storage/entity-canonical-id-migration-adapter.ts +16 -1
- package/src/storage/entity-canonical-id-migration.ts +17 -8
- package/src/storage/entity-canonical-id-references.ts +24 -0
- package/src/storage/entity-migration-completion-cache.nofollow.test.ts +223 -0
- package/src/storage/entity-migration-completion-cache.ts +153 -0
- package/src/storage/entity-store.ts +58 -86
- package/src/storage/memory-read-store.ts +9 -3
- package/src/storage/windowed-memory-read.ts +8 -0
- package/src/storage-startup-nonblocking-migration.test.ts +183 -0
- package/src/storage.ts +9 -3
- package/src/testing/subjects/entity-migration-completion-cache.test.ts +90 -0
- package/dist/chunk-3DKKZVXS.js.map +0 -1
- package/dist/chunk-CCTLRRV6.js.map +0 -1
- package/dist/chunk-CHSRA76M.js.map +0 -1
- package/dist/chunk-FRXS6SC7.js.map +0 -1
- package/dist/chunk-FWV2SXSL.js.map +0 -1
- package/dist/chunk-L46MG2GE.js.map +0 -1
- package/dist/chunk-LWRIGKFM.js.map +0 -1
- package/dist/chunk-OXSTKCYK.js.map +0 -1
- package/dist/chunk-PKPOO6X5.js.map +0 -1
- package/dist/chunk-SUKPM6DV.js.map +0 -1
- package/dist/chunk-UXAF4RQM.js.map +0 -1
- package/dist/chunk-VY6BD5KB.js.map +0 -1
- package/dist/chunk-Y57GJDG5.js.map +0 -1
- package/dist/chunk-YBKQAVPZ.js.map +0 -1
- package/dist/chunk-YUE7J2HZ.js.map +0 -1
- /package/dist/{auto-sync-BNCBMU6H.js.map → auto-sync-UQQ6YJSB.js.map} +0 -0
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → briefing-deadline.js.map} +0 -0
- /package/dist/{entity-canonical-id-migration-2YOLMOFC.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{capsule-merge-RNQUP2VL.js.map → capsule-merge-D4BTIJGK.js.map} +0 -0
- /package/dist/{graph-edge-decay-3HVLMT6U.js.map → capture-write-lock-scope.js.map} +0 -0
- /package/dist/{chunk-FAKRTS3Y.js.map → chunk-2AKIVSHP.js.map} +0 -0
- /package/dist/{chunk-EIYJK7OD.js.map → chunk-2M36PR7R.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-6P6MZDBL.js.map → chunk-3NL4ALUP.js.map} +0 -0
- /package/dist/{chunk-6CC2YCKG.js.map → chunk-43TUWQNR.js.map} +0 -0
- /package/dist/{chunk-H7BZBSP6.js.map → chunk-52II7PB6.js.map} +0 -0
- /package/dist/{chunk-2NLCDNGA.js.map → chunk-564YP3DW.js.map} +0 -0
- /package/dist/{chunk-5KGYR5VN.js.map → chunk-5DVOBBTV.js.map} +0 -0
- /package/dist/{chunk-RT2GN6KQ.js.map → chunk-5FUDSK6Z.js.map} +0 -0
- /package/dist/{chunk-B4XSXFKI.js.map → chunk-5G53JSRO.js.map} +0 -0
- /package/dist/{chunk-BGK3SFCC.js.map → chunk-5X2H3X4J.js.map} +0 -0
- /package/dist/{chunk-4J7BNL7B.js.map → chunk-6ZQX3R66.js.map} +0 -0
- /package/dist/{chunk-JNLYHJG7.js.map → chunk-74AY3S7U.js.map} +0 -0
- /package/dist/{chunk-RUAIO5UA.js.map → chunk-7J6A5MV2.js.map} +0 -0
- /package/dist/{chunk-A45QXZMU.js.map → chunk-7SAE6T36.js.map} +0 -0
- /package/dist/{chunk-QE2XQM3S.js.map → chunk-7YVER7ZO.js.map} +0 -0
- /package/dist/{chunk-IJH6METJ.js.map → chunk-A3UFV4K3.js.map} +0 -0
- /package/dist/{chunk-LXN737FX.js.map → chunk-AAANTXCQ.js.map} +0 -0
- /package/dist/{chunk-I3IPXGFQ.js.map → chunk-AJJPXUE6.js.map} +0 -0
- /package/dist/{chunk-2DPJFJFH.js.map → chunk-BNJAVRNJ.js.map} +0 -0
- /package/dist/{chunk-YL564QS2.js.map → chunk-CCL2OXFO.js.map} +0 -0
- /package/dist/{chunk-ZX5N5D6M.js.map → chunk-DAOMWGO2.js.map} +0 -0
- /package/dist/{chunk-23ZMQONL.js.map → chunk-ERMT5WQM.js.map} +0 -0
- /package/dist/{chunk-VTCNVGM6.js.map → chunk-EWBXMGXR.js.map} +0 -0
- /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
- /package/dist/{chunk-XTN54NML.js.map → chunk-G3T6YMBO.js.map} +0 -0
- /package/dist/{chunk-2JNBPOZ2.js.map → chunk-GDYLZ6FR.js.map} +0 -0
- /package/dist/{chunk-DZPTR2XQ.js.map → chunk-GFAEKSFR.js.map} +0 -0
- /package/dist/{chunk-M7LA4QBY.js.map → chunk-GXVXBYRA.js.map} +0 -0
- /package/dist/{chunk-JGMJZBFV.js.map → chunk-HPNXS6W6.js.map} +0 -0
- /package/dist/{chunk-BFPF5N3H.js.map → chunk-HXFIILGF.js.map} +0 -0
- /package/dist/{chunk-CMNL3QSL.js.map → chunk-IN6U2BS5.js.map} +0 -0
- /package/dist/{chunk-BWRX322G.js.map → chunk-IUYXCTA7.js.map} +0 -0
- /package/dist/{chunk-LU57EEJW.js.map → chunk-JBWD3J5U.js.map} +0 -0
- /package/dist/{chunk-2V664H6O.js.map → chunk-JS44PBCM.js.map} +0 -0
- /package/dist/{chunk-XKTHJHSQ.js.map → chunk-JZCBMKR5.js.map} +0 -0
- /package/dist/{chunk-MXPVNDGO.js.map → chunk-K5QQXVG6.js.map} +0 -0
- /package/dist/{chunk-BUKK5SWA.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-WUBGMV3G.js.map → chunk-KRAMCBIW.js.map} +0 -0
- /package/dist/{chunk-NDMPRT3Z.js.map → chunk-KW5YZELC.js.map} +0 -0
- /package/dist/{chunk-2RQR4TXV.js.map → chunk-LIBVANOF.js.map} +0 -0
- /package/dist/{chunk-M7L5A2AT.js.map → chunk-LMMBV7QC.js.map} +0 -0
- /package/dist/{chunk-PJBYVJKO.js.map → chunk-LXXIV7Y2.js.map} +0 -0
- /package/dist/{chunk-MZCTS3ZG.js.map → chunk-M2DOJBH7.js.map} +0 -0
- /package/dist/{chunk-WOPZ2P5Z.js.map → chunk-M4HRYLOA.js.map} +0 -0
- /package/dist/{chunk-JCYEDMOY.js.map → chunk-M6TP6UYD.js.map} +0 -0
- /package/dist/{chunk-KAUCVTAW.js.map → chunk-MLNXATFG.js.map} +0 -0
- /package/dist/{chunk-2NX7JTST.js.map → chunk-MPWOAIIH.js.map} +0 -0
- /package/dist/{chunk-RQLTCHUL.js.map → chunk-MWURUSRE.js.map} +0 -0
- /package/dist/{chunk-3EGL7XZO.js.map → chunk-N74WJ7B2.js.map} +0 -0
- /package/dist/{chunk-DRXTMDAG.js.map → chunk-N7FNCE7F.js.map} +0 -0
- /package/dist/{chunk-6CWAY4R7.js.map → chunk-NPLM7AFU.js.map} +0 -0
- /package/dist/{chunk-VECRSYQG.js.map → chunk-NRGQ5HJO.js.map} +0 -0
- /package/dist/{chunk-PPDNG7WC.js.map → chunk-NSP5PIQH.js.map} +0 -0
- /package/dist/{chunk-6HVLHIAB.js.map → chunk-P7OVFGMU.js.map} +0 -0
- /package/dist/{chunk-EX27VKU6.js.map → chunk-PDTNQLPC.js.map} +0 -0
- /package/dist/{chunk-ME5LVISI.js.map → chunk-PJCVI44H.js.map} +0 -0
- /package/dist/{chunk-LJCHDFLP.js.map → chunk-Q3PNQYAC.js.map} +0 -0
- /package/dist/{chunk-YFJHFEET.js.map → chunk-QS765SBL.js.map} +0 -0
- /package/dist/{chunk-FJ264QBP.js.map → chunk-QTDZ2NYC.js.map} +0 -0
- /package/dist/{chunk-Q6UZREJK.js.map → chunk-RKRX4C4H.js.map} +0 -0
- /package/dist/{chunk-GLZWOIU3.js.map → chunk-SJTSWG2Z.js.map} +0 -0
- /package/dist/{chunk-XM747YJF.js.map → chunk-TFWJXWL6.js.map} +0 -0
- /package/dist/{chunk-QFQ4UG3I.js.map → chunk-TXKQBQYW.js.map} +0 -0
- /package/dist/{chunk-BMOJFGVX.js.map → chunk-UALXWWGN.js.map} +0 -0
- /package/dist/{chunk-B44NFHWI.js.map → chunk-UNOAVHV4.js.map} +0 -0
- /package/dist/{chunk-TF5NZGPS.js.map → chunk-UQBOPCDK.js.map} +0 -0
- /package/dist/{chunk-5R2IF2KI.js.map → chunk-UXGXJUZ5.js.map} +0 -0
- /package/dist/{chunk-J6B6FK2X.js.map → chunk-VCOMACR6.js.map} +0 -0
- /package/dist/{chunk-WCGJK4NQ.js.map → chunk-VKQI47DJ.js.map} +0 -0
- /package/dist/{chunk-MPJDQC4G.js.map → chunk-WJCXUE2J.js.map} +0 -0
- /package/dist/{chunk-BCDECPVO.js.map → chunk-WV4UYDP6.js.map} +0 -0
- /package/dist/{chunk-VWJ56T63.js.map → chunk-WXJC2L66.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-FPANDKMQ.js.map → chunk-XC3H7KON.js.map} +0 -0
- /package/dist/{chunk-OOOX5C4X.js.map → chunk-XL2EE5W3.js.map} +0 -0
- /package/dist/{chunk-3SL52JKD.js.map → chunk-XVZA6VXC.js.map} +0 -0
- /package/dist/{chunk-CZVNOTLR.js.map → chunk-XXR4A33N.js.map} +0 -0
- /package/dist/{chunk-2AV2U2SZ.js.map → chunk-YDIOMDBW.js.map} +0 -0
- /package/dist/{chunk-XTVH2NAW.js.map → chunk-YECEEJUU.js.map} +0 -0
- /package/dist/{chunk-QR6W3FSW.js.map → chunk-Z5277JWF.js.map} +0 -0
- /package/dist/{chunk-CTHYR4QK.js.map → chunk-ZFNXJEUG.js.map} +0 -0
- /package/dist/{chunk-6Q56WDHG.js.map → chunk-ZLCBLDJO.js.map} +0 -0
- /package/dist/{chunk-KRACAE73.js.map → chunk-ZNRTHYYW.js.map} +0 -0
- /package/dist/{chunk-7AIPWNM7.js.map → chunk-ZSMA67FV.js.map} +0 -0
|
@@ -19,11 +19,11 @@ import {
|
|
|
19
19
|
getFingerprint,
|
|
20
20
|
migrateLegacyEntityCanonicalIds,
|
|
21
21
|
validateRoots
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ZMO2S5RT.js";
|
|
23
23
|
import {
|
|
24
24
|
normalizeQmdResultPath,
|
|
25
25
|
resolveNamespaceResultPath
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-LXXIV7Y2.js";
|
|
27
27
|
import {
|
|
28
28
|
withholdToolScopedFromSharedNamespace
|
|
29
29
|
} from "./chunk-S2V7RUCL.js";
|
|
@@ -34,13 +34,16 @@ import {
|
|
|
34
34
|
import {
|
|
35
35
|
parseOfflineSyncDigestCache
|
|
36
36
|
} from "./chunk-X3724WL4.js";
|
|
37
|
+
import {
|
|
38
|
+
createMemorySnapshot
|
|
39
|
+
} from "./chunk-S2HLHAZ4.js";
|
|
37
40
|
import {
|
|
38
41
|
rewriteProjectedEntityReferences,
|
|
39
42
|
rewriteProjectedMemoryEntityReference
|
|
40
43
|
} from "./chunk-MRPOZBJC.js";
|
|
41
44
|
import {
|
|
42
|
-
|
|
43
|
-
} from "./chunk-
|
|
45
|
+
rotateMarkdownFileToArchive
|
|
46
|
+
} from "./chunk-DM2T26WE.js";
|
|
44
47
|
import {
|
|
45
48
|
closeContinuityIncidentRecord,
|
|
46
49
|
createContinuityIncidentRecord,
|
|
@@ -50,9 +53,6 @@ import {
|
|
|
50
53
|
serializeContinuityIncident,
|
|
51
54
|
upsertContinuityLoopInMarkdown
|
|
52
55
|
} from "./chunk-LDXUBPMO.js";
|
|
53
|
-
import {
|
|
54
|
-
rotateMarkdownFileToArchive
|
|
55
|
-
} from "./chunk-DM2T26WE.js";
|
|
56
56
|
import {
|
|
57
57
|
parseProvenanceSources,
|
|
58
58
|
parseProvenanceTag,
|
|
@@ -70,15 +70,12 @@ import {
|
|
|
70
70
|
invalidationCommitFingerprint,
|
|
71
71
|
parseTombstoneBlockedOfflineSyncMemory,
|
|
72
72
|
withCasCommitReceipt
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-WJCXUE2J.js";
|
|
74
74
|
import {
|
|
75
75
|
matchEntitySchemaSection,
|
|
76
76
|
normalizeEntityStructuredSection,
|
|
77
77
|
sortStructuredSectionsBySchema
|
|
78
78
|
} from "./chunk-ZIKENA2C.js";
|
|
79
|
-
import {
|
|
80
|
-
normalizeEntityName
|
|
81
|
-
} from "./chunk-YXZG5TVN.js";
|
|
82
79
|
import {
|
|
83
80
|
OKF_QUESTION_TYPE,
|
|
84
81
|
assertNotOkfReservedBasename,
|
|
@@ -92,18 +89,17 @@ import {
|
|
|
92
89
|
normalizeProjectionTags
|
|
93
90
|
} from "./chunk-SCU65EZI.js";
|
|
94
91
|
import {
|
|
95
|
-
|
|
96
|
-
} from "./chunk-
|
|
92
|
+
normalizeEntityName
|
|
93
|
+
} from "./chunk-YXZG5TVN.js";
|
|
97
94
|
import {
|
|
98
95
|
detectLanguageHint
|
|
99
96
|
} from "./chunk-3WU7XOFN.js";
|
|
100
97
|
import {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
} from "./chunk-G7D6GZ5J.js";
|
|
98
|
+
checkCorpusReadAbort
|
|
99
|
+
} from "./chunk-P4GUQSK3.js";
|
|
104
100
|
import {
|
|
105
101
|
createVersion
|
|
106
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-564YP3DW.js";
|
|
107
103
|
import {
|
|
108
104
|
attachInFlightReader,
|
|
109
105
|
beginCoalescedScan,
|
|
@@ -112,24 +108,41 @@ import {
|
|
|
112
108
|
deleteInFlightReadsForDir
|
|
113
109
|
} from "./chunk-RBOJCG4T.js";
|
|
114
110
|
import {
|
|
111
|
+
ENTITY_CANONICAL_ID_MIGRATION_FILE,
|
|
112
|
+
ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER,
|
|
113
|
+
ENTITY_CANONICAL_ID_RECONCILE_MARKER,
|
|
115
114
|
HistoricalEntityCanonicalIdCache,
|
|
116
115
|
appendCanonicalizedTombstone,
|
|
117
116
|
assertSafeEntityId,
|
|
118
117
|
canonicalizeEntityRefFrontmatter,
|
|
119
118
|
canonicalizeEntityRefOption,
|
|
119
|
+
entityCanonicalIdMigrationCompleted,
|
|
120
120
|
memoizedJournalCompletion,
|
|
121
121
|
reconcileIfJournalMovedSync,
|
|
122
122
|
repairEntityRefAfterJournalMove,
|
|
123
123
|
requestEntityCanonicalIdReconcileSync,
|
|
124
124
|
resolveHistoricalEntityCanonicalId,
|
|
125
125
|
withEntityCanonicalMutationLock
|
|
126
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-A5L5KGDI.js";
|
|
127
127
|
import {
|
|
128
128
|
supersessionKeysForFact
|
|
129
129
|
} from "./chunk-5WITETWU.js";
|
|
130
130
|
import {
|
|
131
131
|
entityMentionEpoch
|
|
132
132
|
} from "./chunk-7CT3AI52.js";
|
|
133
|
+
import {
|
|
134
|
+
isConsolidationOperator,
|
|
135
|
+
isValidDerivedFromEntry
|
|
136
|
+
} from "./chunk-G7D6GZ5J.js";
|
|
137
|
+
import {
|
|
138
|
+
scopedCaptureWriteLockLimits
|
|
139
|
+
} from "./chunk-7VLBZKNB.js";
|
|
140
|
+
import {
|
|
141
|
+
buildCapturePathLockIdentity,
|
|
142
|
+
buildExplicitCaptureDedupKey,
|
|
143
|
+
isQueuedReviewMemory,
|
|
144
|
+
tombstoneBlocked
|
|
145
|
+
} from "./chunk-UUZ7KZAO.js";
|
|
133
146
|
import {
|
|
134
147
|
parseOriginClass
|
|
135
148
|
} from "./chunk-23G5P7TA.js";
|
|
@@ -146,12 +159,6 @@ import {
|
|
|
146
159
|
updateCacheOnDelete,
|
|
147
160
|
updateCacheOnWrite
|
|
148
161
|
} from "./chunk-C64XATK7.js";
|
|
149
|
-
import {
|
|
150
|
-
buildCapturePathLockIdentity,
|
|
151
|
-
buildExplicitCaptureDedupKey,
|
|
152
|
-
isQueuedReviewMemory,
|
|
153
|
-
tombstoneBlocked
|
|
154
|
-
} from "./chunk-UUZ7KZAO.js";
|
|
155
162
|
import {
|
|
156
163
|
selectArtifactMatches
|
|
157
164
|
} from "./chunk-HADD45AR.js";
|
|
@@ -238,7 +245,8 @@ import {
|
|
|
238
245
|
} from "./chunk-C5LWPYS3.js";
|
|
239
246
|
import {
|
|
240
247
|
isAbortError,
|
|
241
|
-
raceAbort
|
|
248
|
+
raceAbort,
|
|
249
|
+
throwIfAborted
|
|
242
250
|
} from "./chunk-R2MBW2S4.js";
|
|
243
251
|
import {
|
|
244
252
|
isMacOsReplicationJunkBasename,
|
|
@@ -278,7 +286,7 @@ import {
|
|
|
278
286
|
|
|
279
287
|
// src/storage.ts
|
|
280
288
|
import {
|
|
281
|
-
lstat as
|
|
289
|
+
lstat as lstat5,
|
|
282
290
|
readdir as readdir6,
|
|
283
291
|
readFile,
|
|
284
292
|
realpath as realpath3,
|
|
@@ -314,7 +322,7 @@ function parseDriftProvenance(fm) {
|
|
|
314
322
|
}
|
|
315
323
|
|
|
316
324
|
// src/storage.ts
|
|
317
|
-
import
|
|
325
|
+
import path15 from "path";
|
|
318
326
|
|
|
319
327
|
// src/storage/tombstone-migration-sources.ts
|
|
320
328
|
import { statSync } from "fs";
|
|
@@ -406,6 +414,7 @@ async function readWindowedMemories(store, options, hotCache, rememberMemorySnap
|
|
|
406
414
|
return timestampMs === null || timestampMs >= updatedAfterMs ? memory : null;
|
|
407
415
|
})
|
|
408
416
|
)).filter((memory) => memory !== null);
|
|
417
|
+
throwIfAborted(options.abortSignal, "windowed memory read aborted");
|
|
409
418
|
const memories = orderWindowMemories(selected, hotCache.baseDir);
|
|
410
419
|
return { memories: rememberMemorySnapshots(memories), filePaths: memories.map((memory) => memory.path) };
|
|
411
420
|
}
|
|
@@ -648,7 +657,8 @@ var MemoryReadStore = class {
|
|
|
648
657
|
return tiers.flat();
|
|
649
658
|
}
|
|
650
659
|
async readMemoriesWindow(options = {}) {
|
|
651
|
-
const
|
|
660
|
+
const readOptions = { abortSignal: options.abortSignal };
|
|
661
|
+
const allPaths = await this.deps.collectActiveMemoryPaths(readOptions);
|
|
652
662
|
const sortedPaths = this.deps.orderWindowPaths(allPaths);
|
|
653
663
|
const maxMemories = typeof options.maxMemories === "number" && Number.isFinite(options.maxMemories) ? Math.max(1, Math.floor(options.maxMemories)) : void 0;
|
|
654
664
|
const maxCandidatePaths = maxMemories === void 0 ? void 0 : maxMemories * 2;
|
|
@@ -657,6 +667,7 @@ var MemoryReadStore = class {
|
|
|
657
667
|
const memories = [];
|
|
658
668
|
const selectedPaths = [];
|
|
659
669
|
for (let i = 0; i < sortedPaths.length; i += normalizedBatchSize) {
|
|
670
|
+
checkCorpusReadAbort(readOptions);
|
|
660
671
|
if (maxMemories !== void 0 && (memories.length >= maxMemories || maxCandidatePaths !== void 0 && selectedPaths.length >= maxCandidatePaths)) {
|
|
661
672
|
return { memories, filePaths: selectedPaths };
|
|
662
673
|
}
|
|
@@ -665,13 +676,14 @@ var MemoryReadStore = class {
|
|
|
665
676
|
const remainingSlots = maxMemories === void 0 ? void 0 : Math.max(0, maxMemories - memories.length);
|
|
666
677
|
const remainingInspectionBudget = maxCandidatePaths === void 0 ? void 0 : Math.max(0, maxCandidatePaths - selectedPaths.length);
|
|
667
678
|
const { memories: batchMemories, filePaths: parsedCandidatePaths } = remainingSlots === void 0 ? {
|
|
668
|
-
memories: await this.deps.readParsedMemoriesFromPaths(candidateBatchPaths, normalizedBatchSize),
|
|
679
|
+
memories: await this.deps.readParsedMemoriesFromPaths(candidateBatchPaths, normalizedBatchSize, readOptions),
|
|
669
680
|
filePaths: candidateBatchPaths
|
|
670
681
|
} : await this.deps.readWindowBoundedBatch(
|
|
671
682
|
candidateBatchPaths,
|
|
672
683
|
remainingSlots,
|
|
673
684
|
remainingInspectionBudget ?? remainingSlots,
|
|
674
|
-
normalizedBatchSize
|
|
685
|
+
normalizedBatchSize,
|
|
686
|
+
readOptions
|
|
675
687
|
);
|
|
676
688
|
selectedPaths.push(...parsedCandidatePaths);
|
|
677
689
|
for (const memory of batchMemories) {
|
|
@@ -1755,8 +1767,110 @@ function selfDeps(self) {
|
|
|
1755
1767
|
}
|
|
1756
1768
|
|
|
1757
1769
|
// src/storage/entity-store.ts
|
|
1758
|
-
import { lstat as
|
|
1770
|
+
import { lstat as lstat3, readdir as readdir2, unlink } from "fs/promises";
|
|
1771
|
+
import path6 from "path";
|
|
1772
|
+
|
|
1773
|
+
// src/storage/entity-migration-completion-cache.ts
|
|
1774
|
+
import { lstat as lstat2, realpath as realpath2 } from "fs/promises";
|
|
1759
1775
|
import path5 from "path";
|
|
1776
|
+
async function isTrustedEntitiesRoot(baseDir, entitiesDir) {
|
|
1777
|
+
let rootStat;
|
|
1778
|
+
try {
|
|
1779
|
+
rootStat = await lstat2(entitiesDir);
|
|
1780
|
+
} catch (err) {
|
|
1781
|
+
if (isErrnoCode(err, "ENOENT")) return false;
|
|
1782
|
+
throw err;
|
|
1783
|
+
}
|
|
1784
|
+
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) return false;
|
|
1785
|
+
let memoryRoot;
|
|
1786
|
+
let entitiesReal;
|
|
1787
|
+
try {
|
|
1788
|
+
memoryRoot = await realpath2(baseDir);
|
|
1789
|
+
entitiesReal = await realpath2(entitiesDir);
|
|
1790
|
+
} catch (err) {
|
|
1791
|
+
if (isErrnoCode(err, "ENOENT")) return false;
|
|
1792
|
+
throw err;
|
|
1793
|
+
}
|
|
1794
|
+
return pathIsInside(memoryRoot, entitiesReal);
|
|
1795
|
+
}
|
|
1796
|
+
var EntityMigrationCompletionCache = class {
|
|
1797
|
+
cache;
|
|
1798
|
+
/** lstat identity for one fingerprint input path; nofollow; missing → stable token. */
|
|
1799
|
+
async inputPathSig(filePath) {
|
|
1800
|
+
try {
|
|
1801
|
+
const s = await lstat2(filePath);
|
|
1802
|
+
return `${s.dev}:${s.ino}:${s.mtimeMs}:${s.ctimeMs}:${s.size}:${s.isSymbolicLink() ? "L" : s.isDirectory() ? "D" : "F"}`;
|
|
1803
|
+
} catch {
|
|
1804
|
+
return "missing";
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Cheap coherence key. entities/ absence is uncacheable (random suffix) so
|
|
1809
|
+
* we never pin a false complete.
|
|
1810
|
+
*/
|
|
1811
|
+
async inputSig(deps) {
|
|
1812
|
+
const stateDir = path5.join(deps.baseDir, "state");
|
|
1813
|
+
const entitiesSig = await this.inputPathSig(deps.entitiesDir);
|
|
1814
|
+
if (entitiesSig === "missing") return `entities-missing:${Math.random()}`;
|
|
1815
|
+
const [aliasesSig, journalSig, reconcileSig, consumingSig] = await Promise.all([
|
|
1816
|
+
this.inputPathSig(path5.join(deps.baseDir, "config", "aliases.json")),
|
|
1817
|
+
this.inputPathSig(path5.join(stateDir, ENTITY_CANONICAL_ID_MIGRATION_FILE)),
|
|
1818
|
+
this.inputPathSig(path5.join(stateDir, ENTITY_CANONICAL_ID_RECONCILE_MARKER)),
|
|
1819
|
+
this.inputPathSig(path5.join(stateDir, ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER))
|
|
1820
|
+
]);
|
|
1821
|
+
return [entitiesSig, aliasesSig, journalSig, reconcileSig, consumingSig].join("|");
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* True when journal completion attests to live fingerprint inputs.
|
|
1825
|
+
* Untrusted entities roots (symlink / outside base) never reach getFingerprint.
|
|
1826
|
+
*/
|
|
1827
|
+
async isCompleted(deps) {
|
|
1828
|
+
const version = deps.getEntityMutationVersion();
|
|
1829
|
+
const inputSig = await this.inputSig(deps);
|
|
1830
|
+
const cached = this.cache;
|
|
1831
|
+
if (cached && cached.version === version && cached.inputSig === inputSig) return cached.completed;
|
|
1832
|
+
if (!await isTrustedEntitiesRoot(deps.baseDir, deps.entitiesDir)) {
|
|
1833
|
+
this.cache = { version, inputSig, completed: false };
|
|
1834
|
+
return false;
|
|
1835
|
+
}
|
|
1836
|
+
const completed = await entityCanonicalIdMigrationCompleted(path5.join(deps.baseDir, "state"), () => getFingerprint(deps.baseDir, deps.entitiesDir, () => String(version)));
|
|
1837
|
+
this.cache = { version, inputSig, completed };
|
|
1838
|
+
return completed;
|
|
1839
|
+
}
|
|
1840
|
+
};
|
|
1841
|
+
async function readEntityFileResolvingRename(deps, firstPath, entityId) {
|
|
1842
|
+
try {
|
|
1843
|
+
return { id: entityId, content: await deps.readStorageSecureFile(firstPath) };
|
|
1844
|
+
} catch (err) {
|
|
1845
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
1846
|
+
if (isErrnoCode(err, "ELOOP")) return null;
|
|
1847
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
1848
|
+
}
|
|
1849
|
+
const historicalIds = deps.currentHistoricalIds();
|
|
1850
|
+
const canonical = resolveHistoricalEntityCanonicalId(entityId, historicalIds);
|
|
1851
|
+
const candidates = /* @__PURE__ */ new Set([canonical]);
|
|
1852
|
+
for (const legacy of Object.keys(historicalIds)) {
|
|
1853
|
+
if (resolveHistoricalEntityCanonicalId(legacy, historicalIds) === canonical) candidates.add(legacy);
|
|
1854
|
+
}
|
|
1855
|
+
candidates.delete(entityId);
|
|
1856
|
+
for (const candidate of candidates) {
|
|
1857
|
+
try {
|
|
1858
|
+
return {
|
|
1859
|
+
id: candidate,
|
|
1860
|
+
content: await deps.readStorageSecureFile(
|
|
1861
|
+
path5.join(deps.entitiesDir, `${candidate}.md`)
|
|
1862
|
+
)
|
|
1863
|
+
};
|
|
1864
|
+
} catch (err) {
|
|
1865
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
1866
|
+
if (isErrnoCode(err, "ENOENT") || isErrnoCode(err, "ELOOP")) continue;
|
|
1867
|
+
throw err;
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
return null;
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
// src/storage/entity-store.ts
|
|
1760
1874
|
var EntityStore = class {
|
|
1761
1875
|
constructor(deps) {
|
|
1762
1876
|
this.deps = deps;
|
|
@@ -1764,6 +1878,7 @@ var EntityStore = class {
|
|
|
1764
1878
|
deps;
|
|
1765
1879
|
/** Filename → file identity of the last indexable check. Unchanged files are not reread. */
|
|
1766
1880
|
entityIndexableCache = /* @__PURE__ */ new Map();
|
|
1881
|
+
migrationCompletion = new EntityMigrationCompletionCache();
|
|
1767
1882
|
/** Normalize an entity name using this store's alias table. */
|
|
1768
1883
|
normalizeEntityName(raw, type) {
|
|
1769
1884
|
return normalizeEntityName(raw, type, this.deps.userAliases);
|
|
@@ -1776,9 +1891,10 @@ var EntityStore = class {
|
|
|
1776
1891
|
* resolving only the canonical path silently drops the mutation.
|
|
1777
1892
|
*/
|
|
1778
1893
|
async readEntityForMutation(name, method, historicalIds) {
|
|
1894
|
+
assertSafeEntityId(name);
|
|
1779
1895
|
const canonical = resolveHistoricalEntityCanonicalId(name, historicalIds);
|
|
1780
1896
|
for (const candidate of canonical === name ? [name] : [canonical, name]) {
|
|
1781
|
-
const filePath =
|
|
1897
|
+
const filePath = path6.join(this.deps.entitiesDir, `${candidate}.md`);
|
|
1782
1898
|
try {
|
|
1783
1899
|
const entity = parseEntityFile(await this.deps.readStorageSecureFile(filePath), this.deps.entitySchemas);
|
|
1784
1900
|
return { filePath, entity };
|
|
@@ -1803,7 +1919,8 @@ var EntityStore = class {
|
|
|
1803
1919
|
* `mutate` returns false to skip the write. Resolves true when written.
|
|
1804
1920
|
*/
|
|
1805
1921
|
async mutateEntityFile(name, method, mutate) {
|
|
1806
|
-
|
|
1922
|
+
await this.deps.ensureDirectories();
|
|
1923
|
+
const stateDir = path6.join(this.deps.baseDir, "state");
|
|
1807
1924
|
return withEntityCanonicalMutationLock(stateDir, async () => {
|
|
1808
1925
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
1809
1926
|
const idsAtResolve = this.deps.currentHistoricalIds();
|
|
@@ -1858,7 +1975,7 @@ var EntityStore = class {
|
|
|
1858
1975
|
async writeEntity(name, type, facts, options = {}) {
|
|
1859
1976
|
await this.deps.ensureDirectories();
|
|
1860
1977
|
return withEntityCanonicalMutationLock(
|
|
1861
|
-
|
|
1978
|
+
path6.join(this.deps.baseDir, "state"),
|
|
1862
1979
|
() => this.writeEntityUnlocked(name, type, facts, options)
|
|
1863
1980
|
);
|
|
1864
1981
|
}
|
|
@@ -1879,7 +1996,7 @@ var EntityStore = class {
|
|
|
1879
1996
|
log.debug(`fuzzy match: "${normalized}" \u2192 existing "${match}"`);
|
|
1880
1997
|
normalized = match;
|
|
1881
1998
|
}
|
|
1882
|
-
const filePath =
|
|
1999
|
+
const filePath = path6.join(this.deps.entitiesDir, `${normalized}.md`);
|
|
1883
2000
|
let entity = {
|
|
1884
2001
|
name,
|
|
1885
2002
|
type,
|
|
@@ -1975,75 +2092,42 @@ var EntityStore = class {
|
|
|
1975
2092
|
log.debug(`wrote entity ${normalized}`);
|
|
1976
2093
|
return normalized;
|
|
1977
2094
|
}
|
|
1978
|
-
async
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
if (err instanceof SecureStoreLockedError) throw err;
|
|
1983
|
-
if (isErrnoCode(err, "ELOOP")) return null;
|
|
1984
|
-
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
1985
|
-
}
|
|
1986
|
-
const historicalIds = this.deps.currentHistoricalIds();
|
|
1987
|
-
const canonical = resolveHistoricalEntityCanonicalId(entityId, historicalIds);
|
|
1988
|
-
const candidates = /* @__PURE__ */ new Set([canonical]);
|
|
1989
|
-
for (const legacy of Object.keys(historicalIds)) {
|
|
1990
|
-
if (resolveHistoricalEntityCanonicalId(legacy, historicalIds) === canonical) candidates.add(legacy);
|
|
1991
|
-
}
|
|
1992
|
-
candidates.delete(entityId);
|
|
1993
|
-
for (const candidate of candidates) {
|
|
2095
|
+
async readEntity(name) {
|
|
2096
|
+
const filePath = this.deps.resolveEntityFilePath(name);
|
|
2097
|
+
if (filePath === null) return "";
|
|
2098
|
+
const readDirect = async () => {
|
|
1994
2099
|
try {
|
|
1995
|
-
return
|
|
1996
|
-
path5.join(this.deps.entitiesDir, `${candidate}.md`)
|
|
1997
|
-
) };
|
|
2100
|
+
return await this.deps.readStorageSecureFile(filePath);
|
|
1998
2101
|
} catch (err) {
|
|
1999
2102
|
if (err instanceof SecureStoreLockedError) throw err;
|
|
2000
|
-
if (isErrnoCode(err, "ENOENT") || isErrnoCode(err, "ELOOP"))
|
|
2103
|
+
if (isErrnoCode(err, "ENOENT") || isErrnoCode(err, "ELOOP")) return void 0;
|
|
2001
2104
|
throw err;
|
|
2002
2105
|
}
|
|
2003
|
-
}
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
const
|
|
2008
|
-
if (
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2106
|
+
};
|
|
2107
|
+
const direct = await readDirect();
|
|
2108
|
+
if (direct !== void 0) return direct;
|
|
2109
|
+
if (await this.migrationCompletion.isCompleted(this.deps)) return "";
|
|
2110
|
+
const renamed = await readEntityFileResolvingRename(this.deps, filePath, name);
|
|
2111
|
+
if (renamed !== null) return renamed.content;
|
|
2112
|
+
let legacy;
|
|
2113
|
+
for (const file of await this.readEntityDirectoryNames()) {
|
|
2114
|
+
if (!file.endsWith(".md") || !await this.isContainedRegularEntityFile(file)) continue;
|
|
2115
|
+
let content;
|
|
2012
2116
|
try {
|
|
2013
|
-
|
|
2117
|
+
content = await this.deps.readStorageSecureFile(path6.join(this.deps.entitiesDir, file));
|
|
2014
2118
|
} catch (err) {
|
|
2015
2119
|
if (err instanceof SecureStoreLockedError) throw err;
|
|
2016
|
-
if (isErrnoCode(err, "ENOENT") || isErrnoCode(err, "ELOOP"))
|
|
2120
|
+
if (isErrnoCode(err, "ENOENT") || isErrnoCode(err, "ELOOP")) continue;
|
|
2017
2121
|
throw err;
|
|
2018
2122
|
}
|
|
2123
|
+
if (isMalformedEntityRecord(content)) continue;
|
|
2124
|
+
const entity = parseEntityFile(content, this.deps.entitySchemas);
|
|
2125
|
+
if (!entity.name.trim() || !entity.type.trim()) continue;
|
|
2126
|
+
if (this.deps.normalizeEntityName(entity.name, entity.type) !== name) continue;
|
|
2127
|
+
if (legacy !== void 0) throw new Error(`Ambiguous legacy entity id: ${name}`);
|
|
2128
|
+
legacy = content;
|
|
2019
2129
|
}
|
|
2020
|
-
return
|
|
2021
|
-
}
|
|
2022
|
-
/**
|
|
2023
|
-
* True when `entities/` is a real directory inside this memory root.
|
|
2024
|
-
* `realpath` on a symlinked root would treat the link target as trusted,
|
|
2025
|
-
* so the check uses `lstat` first and refuses the scan when the root
|
|
2026
|
-
* itself is a symlink.
|
|
2027
|
-
*/
|
|
2028
|
-
async isTrustedEntitiesRoot() {
|
|
2029
|
-
let rootStat;
|
|
2030
|
-
try {
|
|
2031
|
-
rootStat = await lstat2(this.deps.entitiesDir);
|
|
2032
|
-
} catch (err) {
|
|
2033
|
-
if (isErrnoCode(err, "ENOENT")) return false;
|
|
2034
|
-
throw err;
|
|
2035
|
-
}
|
|
2036
|
-
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) return false;
|
|
2037
|
-
let memoryRoot;
|
|
2038
|
-
let entitiesReal;
|
|
2039
|
-
try {
|
|
2040
|
-
memoryRoot = await realpath2(this.deps.baseDir);
|
|
2041
|
-
entitiesReal = await realpath2(this.deps.entitiesDir);
|
|
2042
|
-
} catch (err) {
|
|
2043
|
-
if (isErrnoCode(err, "ENOENT")) return false;
|
|
2044
|
-
throw err;
|
|
2045
|
-
}
|
|
2046
|
-
return pathIsInside(memoryRoot, entitiesReal);
|
|
2130
|
+
return await readDirect() ?? legacy ?? "";
|
|
2047
2131
|
}
|
|
2048
2132
|
/**
|
|
2049
2133
|
* Entity directory listing with macOS replication junk removed.
|
|
@@ -2051,7 +2135,7 @@ var EntityStore = class {
|
|
|
2051
2135
|
* A symlinked entities root yields an empty list and is not read.
|
|
2052
2136
|
*/
|
|
2053
2137
|
async readEntityDirectoryNames() {
|
|
2054
|
-
if (!await this.
|
|
2138
|
+
if (!await isTrustedEntitiesRoot(this.deps.baseDir, this.deps.entitiesDir)) return [];
|
|
2055
2139
|
const entries = await readdir2(this.deps.entitiesDir);
|
|
2056
2140
|
const { kept, ignored } = withoutMacOsReplicationJunk(entries, (name) => name);
|
|
2057
2141
|
warnIgnoredMacOsReplicationJunk(this.deps.entitiesDir, ignored, (message) => {
|
|
@@ -2066,7 +2150,7 @@ var EntityStore = class {
|
|
|
2066
2150
|
*/
|
|
2067
2151
|
async isMissingEntry(file) {
|
|
2068
2152
|
try {
|
|
2069
|
-
await
|
|
2153
|
+
await lstat3(path6.join(this.deps.entitiesDir, file));
|
|
2070
2154
|
return false;
|
|
2071
2155
|
} catch (err) {
|
|
2072
2156
|
if (isErrnoCode(err, "ENOENT")) return true;
|
|
@@ -2074,10 +2158,10 @@ var EntityStore = class {
|
|
|
2074
2158
|
}
|
|
2075
2159
|
}
|
|
2076
2160
|
async isContainedRegularEntityFile(file) {
|
|
2077
|
-
const filePath =
|
|
2161
|
+
const filePath = path6.join(this.deps.entitiesDir, file);
|
|
2078
2162
|
let entryStat;
|
|
2079
2163
|
try {
|
|
2080
|
-
entryStat = await
|
|
2164
|
+
entryStat = await lstat3(filePath);
|
|
2081
2165
|
} catch (err) {
|
|
2082
2166
|
if (isErrnoCode(err, "ENOENT")) return false;
|
|
2083
2167
|
throw err;
|
|
@@ -2091,10 +2175,10 @@ var EntityStore = class {
|
|
|
2091
2175
|
* reread the whole directory on every extraction write.
|
|
2092
2176
|
*/
|
|
2093
2177
|
async isIndexableEntityMarkdown(file) {
|
|
2094
|
-
const filePath =
|
|
2178
|
+
const filePath = path6.join(this.deps.entitiesDir, file);
|
|
2095
2179
|
let entryStat;
|
|
2096
2180
|
try {
|
|
2097
|
-
entryStat = await
|
|
2181
|
+
entryStat = await lstat3(filePath);
|
|
2098
2182
|
} catch (err) {
|
|
2099
2183
|
if (isErrnoCode(err, "ENOENT")) return false;
|
|
2100
2184
|
throw err;
|
|
@@ -2165,19 +2249,26 @@ var EntityStore = class {
|
|
|
2165
2249
|
}
|
|
2166
2250
|
/** Re-serialize every entity file into the compiled-truth timeline shape. */
|
|
2167
2251
|
async migrateEntityFilesToCompiledTruthTimeline() {
|
|
2252
|
+
await this.deps.ensureDirectories();
|
|
2168
2253
|
const entityNames = await this.listEntityNames();
|
|
2169
|
-
const stateDir =
|
|
2254
|
+
const stateDir = path6.join(this.deps.baseDir, "state");
|
|
2170
2255
|
let migrated = 0;
|
|
2171
2256
|
for (const entityName of entityNames) {
|
|
2172
2257
|
const wrote = await withEntityCanonicalMutationLock(stateDir, async () => {
|
|
2173
|
-
const
|
|
2258
|
+
const filePath = this.deps.resolveEntityFilePath(entityName);
|
|
2259
|
+
if (filePath === null) return false;
|
|
2260
|
+
let raw;
|
|
2261
|
+
try {
|
|
2262
|
+
raw = await this.deps.readStorageSecureFile(filePath);
|
|
2263
|
+
} catch (err) {
|
|
2264
|
+
if (err instanceof SecureStoreLockedError || !isErrnoCode(err, "ENOENT")) throw err;
|
|
2265
|
+
return false;
|
|
2266
|
+
}
|
|
2174
2267
|
if (!raw || isMalformedEntityRecord(raw)) return false;
|
|
2175
2268
|
const parsed = parseEntityFile(raw, this.deps.entitySchemas);
|
|
2176
2269
|
if (!parsed.name.trim() || !parsed.type.trim()) return false;
|
|
2177
2270
|
const serialized = serializeEntityFile(parsed, this.deps.entitySchemas, this.deps.okfConformanceEnabled());
|
|
2178
2271
|
if (raw.trimEnd() === serialized.trimEnd()) return false;
|
|
2179
|
-
const filePath = this.deps.resolveEntityFilePath(entityName);
|
|
2180
|
-
if (filePath === null) return false;
|
|
2181
2272
|
await this.deps.writeStorageSecureFile(filePath, serialized);
|
|
2182
2273
|
this.deps.bumpEntityMutationVersion();
|
|
2183
2274
|
return true;
|
|
@@ -2194,23 +2285,16 @@ var EntityStore = class {
|
|
|
2194
2285
|
* Set or rewrite the synthesis layer of an entity file.
|
|
2195
2286
|
*/
|
|
2196
2287
|
async updateEntitySynthesis(name, synthesis, options = {}) {
|
|
2288
|
+
await this.deps.ensureDirectories();
|
|
2197
2289
|
return withEntityCanonicalMutationLock(
|
|
2198
|
-
|
|
2290
|
+
path6.join(this.deps.baseDir, "state"),
|
|
2199
2291
|
() => this.updateEntitySynthesisUnlocked(name, synthesis, options)
|
|
2200
2292
|
);
|
|
2201
2293
|
}
|
|
2202
2294
|
async updateEntitySynthesisUnlocked(name, synthesis, options = {}) {
|
|
2203
|
-
const
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
const content = await this.deps.readStorageSecureFile(filePath);
|
|
2207
|
-
entity = parseEntityFile(content, this.deps.entitySchemas);
|
|
2208
|
-
} catch (err) {
|
|
2209
|
-
if (err instanceof SecureStoreLockedError) throw err;
|
|
2210
|
-
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
2211
|
-
log.debug(`updateEntitySynthesis: entity file ${name}.md not found`);
|
|
2212
|
-
return;
|
|
2213
|
-
}
|
|
2295
|
+
const located = await this.readEntityForMutation(name, "updateEntitySynthesis", this.deps.currentHistoricalIds());
|
|
2296
|
+
if (!located) return;
|
|
2297
|
+
const { filePath, entity } = located;
|
|
2214
2298
|
const updatedAt = options.updatedAt?.trim() || entity.synthesisUpdatedAt?.trim() || void 0;
|
|
2215
2299
|
const entityUpdatedAt = options.entityUpdatedAt?.trim() || updatedAt || entity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2216
2300
|
const synthesisTimelineCount = Number.isInteger(options.synthesisTimelineCount) && (options.synthesisTimelineCount ?? 0) >= 0 ? options.synthesisTimelineCount : void 0;
|
|
@@ -2247,7 +2331,7 @@ var EntityStore = class {
|
|
|
2247
2331
|
const cached = getCachedEntities(this.deps.baseDir, currentVersion, cacheKey);
|
|
2248
2332
|
if (cached) return cached;
|
|
2249
2333
|
try {
|
|
2250
|
-
if (!await this.
|
|
2334
|
+
if (!await isTrustedEntitiesRoot(this.deps.baseDir, this.deps.entitiesDir)) return [];
|
|
2251
2335
|
const listed = await readdir2(this.deps.entitiesDir);
|
|
2252
2336
|
const { kept: entries, ignored } = withoutMacOsReplicationJunk(listed, (name) => name);
|
|
2253
2337
|
warnIgnoredMacOsReplicationJunk(this.deps.entitiesDir, ignored, (message) => {
|
|
@@ -2265,15 +2349,15 @@ var EntityStore = class {
|
|
|
2265
2349
|
const results = await Promise.all(
|
|
2266
2350
|
batch.map(async (entry) => {
|
|
2267
2351
|
const entityId = entry.slice(0, -".md".length);
|
|
2268
|
-
const entryPath =
|
|
2352
|
+
const entryPath = path6.join(this.deps.entitiesDir, entry);
|
|
2269
2353
|
try {
|
|
2270
2354
|
if (!await this.isContainedRegularEntityFile(entry)) {
|
|
2271
2355
|
if (await this.isMissingEntry(entry)) {
|
|
2272
|
-
return await this.
|
|
2356
|
+
return await readEntityFileResolvingRename(this.deps, entryPath, entityId);
|
|
2273
2357
|
}
|
|
2274
2358
|
return null;
|
|
2275
2359
|
}
|
|
2276
|
-
return await this.
|
|
2360
|
+
return await readEntityFileResolvingRename(this.deps, entryPath, entityId);
|
|
2277
2361
|
} catch (err) {
|
|
2278
2362
|
if (err instanceof SecureStoreLockedError || err instanceof SecureStoreDecryptError) throw err;
|
|
2279
2363
|
log.warn(`entity read isolated failure for ${entry}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -2358,8 +2442,9 @@ ${rows.join("\n")}
|
|
|
2358
2442
|
* Returns count of files merged.
|
|
2359
2443
|
*/
|
|
2360
2444
|
async mergeFragmentedEntities() {
|
|
2445
|
+
await this.deps.ensureDirectories();
|
|
2361
2446
|
return withEntityCanonicalMutationLock(
|
|
2362
|
-
|
|
2447
|
+
path6.join(this.deps.baseDir, "state"),
|
|
2363
2448
|
() => this.mergeFragmentedEntitiesUnlocked()
|
|
2364
2449
|
);
|
|
2365
2450
|
}
|
|
@@ -2387,7 +2472,7 @@ ${rows.join("\n")}
|
|
|
2387
2472
|
const canonicalDestinationOccupied = async (canonicalName, members) => {
|
|
2388
2473
|
if (members.includes(canonicalName)) return false;
|
|
2389
2474
|
try {
|
|
2390
|
-
await
|
|
2475
|
+
await lstat3(path6.join(this.deps.entitiesDir, canonicalName));
|
|
2391
2476
|
return true;
|
|
2392
2477
|
} catch (err) {
|
|
2393
2478
|
if (isErrnoCode(err, "ENOENT")) return false;
|
|
@@ -2424,7 +2509,7 @@ ${rows.join("\n")}
|
|
|
2424
2509
|
extraSections: []
|
|
2425
2510
|
};
|
|
2426
2511
|
for (const file of files) {
|
|
2427
|
-
const filePath =
|
|
2512
|
+
const filePath = path6.join(this.deps.entitiesDir, file);
|
|
2428
2513
|
try {
|
|
2429
2514
|
const content = await this.deps.readStorageSecureFile(filePath);
|
|
2430
2515
|
const parsed = parseEntityFile(content, this.deps.entitySchemas);
|
|
@@ -2577,7 +2662,7 @@ ${rows.join("\n")}
|
|
|
2577
2662
|
}
|
|
2578
2663
|
mergedEntity.created = mergedEntity.created || mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2579
2664
|
mergedEntity.updated = mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2580
|
-
const canonicalPath =
|
|
2665
|
+
const canonicalPath = path6.join(this.deps.entitiesDir, canonicalName);
|
|
2581
2666
|
if (await canonicalDestinationOccupied(canonicalName, files)) {
|
|
2582
2667
|
log.warn(`skipped entity merge into occupied ${canonicalName}`);
|
|
2583
2668
|
continue;
|
|
@@ -2585,7 +2670,7 @@ ${rows.join("\n")}
|
|
|
2585
2670
|
await this.deps.writeStorageSecureFile(canonicalPath, serializeEntityFile(mergedEntity, this.deps.entitySchemas, this.deps.okfConformanceEnabled()));
|
|
2586
2671
|
this.deps.bumpEntityMutationVersion();
|
|
2587
2672
|
for (const file of files) {
|
|
2588
|
-
const filePath =
|
|
2673
|
+
const filePath = path6.join(this.deps.entitiesDir, file);
|
|
2589
2674
|
if (filePath !== canonicalPath) {
|
|
2590
2675
|
try {
|
|
2591
2676
|
await unlink(filePath);
|
|
@@ -2605,7 +2690,7 @@ ${rows.join("\n")}
|
|
|
2605
2690
|
|
|
2606
2691
|
// src/storage/identity-continuity-store.ts
|
|
2607
2692
|
import { readdir as readdir3 } from "fs/promises";
|
|
2608
|
-
import
|
|
2693
|
+
import path7 from "path";
|
|
2609
2694
|
var IdentityContinuityStore = class {
|
|
2610
2695
|
constructor(deps) {
|
|
2611
2696
|
this.deps = deps;
|
|
@@ -2630,7 +2715,7 @@ var IdentityContinuityStore = class {
|
|
|
2630
2715
|
const date = nowIso.slice(0, 10);
|
|
2631
2716
|
const id = this.deps.generateId("incident");
|
|
2632
2717
|
const incident = createContinuityIncidentRecord(id, input, nowIso);
|
|
2633
|
-
const filePath =
|
|
2718
|
+
const filePath = path7.join(this.deps.identityIncidentsDir, `${date}-${id}.md`);
|
|
2634
2719
|
await this.deps.writeStorageSecureFile(filePath, serializeContinuityIncident(incident));
|
|
2635
2720
|
return { ...incident, filePath };
|
|
2636
2721
|
}
|
|
@@ -2643,7 +2728,7 @@ var IdentityContinuityStore = class {
|
|
|
2643
2728
|
const incidents = [];
|
|
2644
2729
|
for (const file of candidates) {
|
|
2645
2730
|
if (incidents.length >= cappedLimit) break;
|
|
2646
|
-
const filePath =
|
|
2731
|
+
const filePath = path7.join(this.deps.identityIncidentsDir, file);
|
|
2647
2732
|
try {
|
|
2648
2733
|
const raw = await this.deps.readStorageSecureFile(filePath);
|
|
2649
2734
|
const parsed = parseContinuityIncident(raw);
|
|
@@ -2674,7 +2759,7 @@ var IdentityContinuityStore = class {
|
|
|
2674
2759
|
await this.deps.ensureDirectories();
|
|
2675
2760
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2676
2761
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2677
|
-
const filePath =
|
|
2762
|
+
const filePath = path7.join(dir, `${safeKey}.md`);
|
|
2678
2763
|
await this.deps.writeStorageSecureFile(filePath, content);
|
|
2679
2764
|
return filePath;
|
|
2680
2765
|
}
|
|
@@ -2682,7 +2767,7 @@ var IdentityContinuityStore = class {
|
|
|
2682
2767
|
try {
|
|
2683
2768
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2684
2769
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2685
|
-
return await this.deps.readStorageSecureFile(
|
|
2770
|
+
return await this.deps.readStorageSecureFile(path7.join(dir, `${safeKey}.md`));
|
|
2686
2771
|
} catch (err) {
|
|
2687
2772
|
if (err instanceof Error && err.message === "Invalid identity audit key") return null;
|
|
2688
2773
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -2738,12 +2823,12 @@ var IdentityContinuityStore = class {
|
|
|
2738
2823
|
const fileNames = await this.readContinuityIncidentFileNames();
|
|
2739
2824
|
const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));
|
|
2740
2825
|
if (directMatch) {
|
|
2741
|
-
const directPath =
|
|
2826
|
+
const directPath = path7.join(this.deps.identityIncidentsDir, directMatch);
|
|
2742
2827
|
const parsed = await this.readContinuityIncidentFile(directPath);
|
|
2743
2828
|
if (parsed?.id === id) return directPath;
|
|
2744
2829
|
}
|
|
2745
2830
|
for (const fileName of fileNames) {
|
|
2746
|
-
const filePath =
|
|
2831
|
+
const filePath = path7.join(this.deps.identityIncidentsDir, fileName);
|
|
2747
2832
|
const parsed = await this.readContinuityIncidentFile(filePath);
|
|
2748
2833
|
if (parsed?.id === id) return filePath;
|
|
2749
2834
|
}
|
|
@@ -2865,6 +2950,7 @@ ${before.content}
|
|
|
2865
2950
|
// src/storage/entity-canonical-id-migration-adapter.ts
|
|
2866
2951
|
async function runLegacyEntityCanonicalIdMigration(host, parseEntityFile2, serializeEntityFile2, serializeMemoryWithEntityRef2) {
|
|
2867
2952
|
const readMigrationFingerprint = () => getFingerprint(host.baseDir, host.entitiesDir, () => String(host.getEntityMutationVersion()));
|
|
2953
|
+
let rewroteReferences = false;
|
|
2868
2954
|
const completionFingerprint = await migrateLegacyEntityCanonicalIds({
|
|
2869
2955
|
stateDir: host.stateDir,
|
|
2870
2956
|
entitiesDir: host.entitiesDir,
|
|
@@ -2887,9 +2973,19 @@ async function runLegacyEntityCanonicalIdMigration(host, parseEntityFile2, seria
|
|
|
2887
2973
|
invalidateKnowledgeIndexCache: host.invalidateKnowledgeIndexCache.bind(host),
|
|
2888
2974
|
invalidateAllMemoriesCache: host.invalidateAllMemoriesCache.bind(host),
|
|
2889
2975
|
invalidateColdMemoriesCache: host.invalidateColdMemoriesCache.bind(host),
|
|
2890
|
-
bumpMemoryStatusVersion:
|
|
2976
|
+
bumpMemoryStatusVersion: () => {
|
|
2977
|
+
rewroteReferences = true;
|
|
2978
|
+
host.bumpMemoryStatusVersion();
|
|
2979
|
+
},
|
|
2891
2980
|
readMigrationFingerprint
|
|
2892
2981
|
});
|
|
2982
|
+
if (completionFingerprint !== void 0 && rewroteReferences) {
|
|
2983
|
+
try {
|
|
2984
|
+
host.onEntityMigrationComplete?.();
|
|
2985
|
+
} catch {
|
|
2986
|
+
log.warn("entity migration: search maintenance scheduling failed");
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2893
2989
|
return completionFingerprint;
|
|
2894
2990
|
}
|
|
2895
2991
|
|
|
@@ -2917,7 +3013,7 @@ var EntityCanonicalIdMigrationRunner = class {
|
|
|
2917
3013
|
await this.ensure();
|
|
2918
3014
|
return;
|
|
2919
3015
|
}
|
|
2920
|
-
const { readSafeEntityEntries } = await import("./entity-canonical-id-migration-
|
|
3016
|
+
const { readSafeEntityEntries } = await import("./entity-canonical-id-migration-ZBNRGUNV.js");
|
|
2921
3017
|
await readSafeEntityEntries(entitiesDir);
|
|
2922
3018
|
}
|
|
2923
3019
|
/**
|
|
@@ -3012,7 +3108,7 @@ import {
|
|
|
3012
3108
|
readFileSync,
|
|
3013
3109
|
realpathSync
|
|
3014
3110
|
} from "fs";
|
|
3015
|
-
import
|
|
3111
|
+
import path8 from "path";
|
|
3016
3112
|
function resolveSafeAliasRoots(baseDir, configDir) {
|
|
3017
3113
|
let baseStat;
|
|
3018
3114
|
try {
|
|
@@ -3039,8 +3135,8 @@ function resolveSafeAliasRoots(baseDir, configDir) {
|
|
|
3039
3135
|
return memoryRoot;
|
|
3040
3136
|
}
|
|
3041
3137
|
function readEntityAliasConfigSync(baseDir) {
|
|
3042
|
-
const configDir =
|
|
3043
|
-
const aliasPath =
|
|
3138
|
+
const configDir = path8.join(baseDir, "config");
|
|
3139
|
+
const aliasPath = path8.join(configDir, "aliases.json");
|
|
3044
3140
|
let memoryRoot = resolveSafeAliasRoots(baseDir, configDir);
|
|
3045
3141
|
if (memoryRoot === void 0) return void 0;
|
|
3046
3142
|
let aliasPreflight;
|
|
@@ -3102,7 +3198,7 @@ function decodeYamlScalar(value) {
|
|
|
3102
3198
|
|
|
3103
3199
|
// src/orchestration/qmd-result-resolver.ts
|
|
3104
3200
|
import { existsSync } from "fs";
|
|
3105
|
-
import
|
|
3201
|
+
import path9 from "path";
|
|
3106
3202
|
var INTERNAL_QMD_ROOTS = /* @__PURE__ */ new Set([
|
|
3107
3203
|
...ALL_CATEGORY_DIRS,
|
|
3108
3204
|
"activity",
|
|
@@ -3124,7 +3220,7 @@ var INTERNAL_QMD_ROOTS = /* @__PURE__ */ new Set([
|
|
|
3124
3220
|
]);
|
|
3125
3221
|
var PRIVATE_RESULT_RESOLUTION_CONCURRENCY = 16;
|
|
3126
3222
|
function qmdCollectionPathParts(resultPath) {
|
|
3127
|
-
if (!resultPath ||
|
|
3223
|
+
if (!resultPath || path9.isAbsolute(resultPath)) return null;
|
|
3128
3224
|
if (resultPath.trim().startsWith("qmd://")) {
|
|
3129
3225
|
try {
|
|
3130
3226
|
const parsed = new URL(resultPath.trim());
|
|
@@ -3149,9 +3245,9 @@ function qmdCollectionPathParts(resultPath) {
|
|
|
3149
3245
|
}
|
|
3150
3246
|
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
3151
3247
|
const candidates = /* @__PURE__ */ new Set();
|
|
3152
|
-
const storageRoot =
|
|
3248
|
+
const storageRoot = path9.resolve(storageDir);
|
|
3153
3249
|
const addCandidate = (candidate) => {
|
|
3154
|
-
const resolved =
|
|
3250
|
+
const resolved = path9.resolve(candidate);
|
|
3155
3251
|
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
3156
3252
|
candidates.add(resolved);
|
|
3157
3253
|
}
|
|
@@ -3159,18 +3255,18 @@ function qmdResultPathCandidates(storageDir, resultPath) {
|
|
|
3159
3255
|
const addRelativeCandidates = (relativePath) => {
|
|
3160
3256
|
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3161
3257
|
if (!normalized) return;
|
|
3162
|
-
addCandidate(
|
|
3258
|
+
addCandidate(path9.join(storageRoot, normalized));
|
|
3163
3259
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3164
|
-
addCandidate(
|
|
3260
|
+
addCandidate(path9.join(storageRoot, "facts", normalized));
|
|
3165
3261
|
}
|
|
3166
3262
|
};
|
|
3167
|
-
if (
|
|
3263
|
+
if (path9.isAbsolute(resultPath)) {
|
|
3168
3264
|
addCandidate(resultPath);
|
|
3169
|
-
const relative2 =
|
|
3170
|
-
if (relative2 && !relative2.startsWith("..") && !
|
|
3171
|
-
const normalized = relative2.split(
|
|
3265
|
+
const relative2 = path9.relative(storageRoot, path9.resolve(resultPath));
|
|
3266
|
+
if (relative2 && !relative2.startsWith("..") && !path9.isAbsolute(relative2)) {
|
|
3267
|
+
const normalized = relative2.split(path9.sep).join("/");
|
|
3172
3268
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3173
|
-
addCandidate(
|
|
3269
|
+
addCandidate(path9.join(storageRoot, "facts", normalized));
|
|
3174
3270
|
}
|
|
3175
3271
|
}
|
|
3176
3272
|
} else {
|
|
@@ -3186,9 +3282,9 @@ function normalizeFlatQmdResults(results, config, collection = config.qmdCollect
|
|
|
3186
3282
|
}));
|
|
3187
3283
|
}
|
|
3188
3284
|
function withHotFactsPath(memoryDir, resolved) {
|
|
3189
|
-
const relative2 =
|
|
3285
|
+
const relative2 = path9.relative(path9.resolve(memoryDir), resolved).split(path9.sep).join("/");
|
|
3190
3286
|
if (!/^\d{4}-\d{2}-\d{2}\//.test(relative2) || existsSync(resolved)) return resolved;
|
|
3191
|
-
const hot =
|
|
3287
|
+
const hot = path9.join(path9.resolve(memoryDir), "facts", relative2);
|
|
3192
3288
|
return existsSync(hot) ? hot : resolved;
|
|
3193
3289
|
}
|
|
3194
3290
|
function storageDirOrNull(storage) {
|
|
@@ -3219,7 +3315,7 @@ var QmdResultResolver = class {
|
|
|
3219
3315
|
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
3220
3316
|
const addStorage = (storage) => {
|
|
3221
3317
|
const storageDir = storageDirOrNull(storage);
|
|
3222
|
-
const storageKey = storageDir ?
|
|
3318
|
+
const storageKey = storageDir ? path9.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
3223
3319
|
if (seenStorageDirs.has(storageKey)) return;
|
|
3224
3320
|
seenStorageDirs.add(storageKey);
|
|
3225
3321
|
storages.push(storage);
|
|
@@ -3249,7 +3345,7 @@ var QmdResultResolver = class {
|
|
|
3249
3345
|
continue;
|
|
3250
3346
|
}
|
|
3251
3347
|
try {
|
|
3252
|
-
const coldRoot =
|
|
3348
|
+
const coldRoot = path9.join(storageDir, "cold");
|
|
3253
3349
|
for (const candidate of qmdResultPathCandidates(coldRoot, parts.relativePath)) {
|
|
3254
3350
|
const memory = await storage.readMemoryByPath(candidate);
|
|
3255
3351
|
if (memory) return memory;
|
|
@@ -3299,9 +3395,9 @@ var QmdResultResolver = class {
|
|
|
3299
3395
|
error: err.message
|
|
3300
3396
|
});
|
|
3301
3397
|
}
|
|
3302
|
-
if (!
|
|
3398
|
+
if (!path9.isAbsolute(fallbackResultPath)) return null;
|
|
3303
3399
|
}
|
|
3304
|
-
if (
|
|
3400
|
+
if (path9.isAbsolute(fallbackResultPath)) {
|
|
3305
3401
|
if (!fallbackStorageDir) {
|
|
3306
3402
|
return await fallbackStorage.readMemoryByPath(fallbackResultPath);
|
|
3307
3403
|
}
|
|
@@ -3358,17 +3454,17 @@ var QmdResultResolver = class {
|
|
|
3358
3454
|
if (!memory && parts && !collectionIsKnownInternal && !collectionIsConfigured) {
|
|
3359
3455
|
memory = await this.readQmdResultMemory(parts.relativePath, fallbackStorage, namespaces, result.namespace);
|
|
3360
3456
|
}
|
|
3361
|
-
const absoluteInsideMemoryRoot =
|
|
3457
|
+
const absoluteInsideMemoryRoot = path9.isAbsolute(result.path) && isPathInsideStorageRoot(path9.resolve(config.memoryDir), path9.resolve(result.path));
|
|
3362
3458
|
const hasExplicitQmdCollection = result.path.trim().startsWith("qmd://");
|
|
3363
3459
|
const unresolvedInternalPath = !memory && (absoluteInsideMemoryRoot || collectionIsKnownInternal && (!preserveUnresolved || hasExplicitQmdCollection) || hasExplicitQmdCollection && collectionIsConfigured);
|
|
3364
|
-
const unresolvedExternalCollection = !memory && (parts !== null && !collectionIsKnownInternal && !collectionIsConfigured ||
|
|
3460
|
+
const unresolvedExternalCollection = !memory && (parts !== null && !collectionIsKnownInternal && !collectionIsConfigured || path9.isAbsolute(result.path) && !isPathInsideStorageRoot(path9.resolve(config.memoryDir), path9.resolve(result.path)));
|
|
3365
3461
|
return memory !== null && !isSupportPassportPrivateMemory(memory) || !memory && !unresolvedInternalPath && (preserveUnresolved || unresolvedExternalCollection);
|
|
3366
3462
|
}
|
|
3367
3463
|
async resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces = []) {
|
|
3368
3464
|
const memory = await this.readQmdResultMemory(result.path, fallbackStorage, recallNamespaces, result.namespace);
|
|
3369
3465
|
if (!memory) return null;
|
|
3370
3466
|
let ownerNamespace = null;
|
|
3371
|
-
if (
|
|
3467
|
+
if (path9.isAbsolute(memory.path)) {
|
|
3372
3468
|
const ownerStorage = await this.storageForAbsoluteQmdResultPath(memory.path, fallbackStorage, recallNamespaces);
|
|
3373
3469
|
ownerNamespace = ownerStorage?.namespace ?? null;
|
|
3374
3470
|
if (!ownerNamespace && resolveNamespaceCapabilities(this.getConfig()).namespaces) return null;
|
|
@@ -3389,17 +3485,17 @@ var QmdResultResolver = class {
|
|
|
3389
3485
|
};
|
|
3390
3486
|
}
|
|
3391
3487
|
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
3392
|
-
const resolvedPath =
|
|
3488
|
+
const resolvedPath = path9.resolve(resultPath);
|
|
3393
3489
|
const config = this.getConfig();
|
|
3394
|
-
const memoryRoot =
|
|
3395
|
-
const namespacesRoot =
|
|
3490
|
+
const memoryRoot = path9.resolve(config.memoryDir);
|
|
3491
|
+
const namespacesRoot = path9.join(memoryRoot, "namespaces");
|
|
3396
3492
|
const fallbackStorageDir = storageDirOrNull(fallbackStorage);
|
|
3397
3493
|
const matches = [];
|
|
3398
3494
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
3399
3495
|
const maybeAddStorage = (storage, namespace) => {
|
|
3400
3496
|
const storageDir = storageDirOrNull(storage);
|
|
3401
3497
|
if (!storageDir) return;
|
|
3402
|
-
const candidateRoot =
|
|
3498
|
+
const candidateRoot = path9.resolve(storageDir);
|
|
3403
3499
|
if (seenDirs.has(candidateRoot)) return;
|
|
3404
3500
|
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
3405
3501
|
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
@@ -3417,7 +3513,7 @@ var QmdResultResolver = class {
|
|
|
3417
3513
|
candidateNamespaces.add(ns);
|
|
3418
3514
|
}
|
|
3419
3515
|
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
3420
|
-
const relativeToNamespaces =
|
|
3516
|
+
const relativeToNamespaces = path9.relative(namespacesRoot, resolvedPath);
|
|
3421
3517
|
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
3422
3518
|
if (namespaceSegment) {
|
|
3423
3519
|
candidateNamespaces.add(namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment);
|
|
@@ -4079,7 +4175,7 @@ function fuseDay(date, inputs, options = {}) {
|
|
|
4079
4175
|
|
|
4080
4176
|
// src/wearables/fusion/store.ts
|
|
4081
4177
|
import { createHash as createHash2 } from "crypto";
|
|
4082
|
-
import * as
|
|
4178
|
+
import * as path10 from "path";
|
|
4083
4179
|
var FUSION_KIND = "wearable-fusion";
|
|
4084
4180
|
function hashFusionBody(conversations) {
|
|
4085
4181
|
return createHash2("sha256").update(JSON.stringify(conversations), "utf-8").digest("hex");
|
|
@@ -4266,7 +4362,7 @@ var FusionArtifactStore = class {
|
|
|
4266
4362
|
`invalid wearable fusion date '${String(date)}' \u2014 expected YYYY-MM-DD`
|
|
4267
4363
|
);
|
|
4268
4364
|
}
|
|
4269
|
-
return
|
|
4365
|
+
return path10.join(this.wearablesDir, FUSION_DIR_NAME, `${date}.md`);
|
|
4270
4366
|
}
|
|
4271
4367
|
async writeFusedDay(date, serialized) {
|
|
4272
4368
|
const filePath = this.fusedDayPath(date);
|
|
@@ -4303,7 +4399,7 @@ var FusionArtifactStore = class {
|
|
|
4303
4399
|
}
|
|
4304
4400
|
/** List dates with stored fused artifacts, newest first. */
|
|
4305
4401
|
async listFusedDays() {
|
|
4306
|
-
const fusionDir =
|
|
4402
|
+
const fusionDir = path10.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4307
4403
|
await this.assertPathContained(fusionDir);
|
|
4308
4404
|
let entries;
|
|
4309
4405
|
try {
|
|
@@ -4347,10 +4443,10 @@ var FusionArtifactStore = class {
|
|
|
4347
4443
|
try {
|
|
4348
4444
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
4349
4445
|
} catch {
|
|
4350
|
-
rootReal =
|
|
4446
|
+
rootReal = path10.resolve(this.memoryDir);
|
|
4351
4447
|
}
|
|
4352
4448
|
await this.assertNoEscape(rootReal, this.wearablesDir);
|
|
4353
|
-
await this.assertNoEscape(rootReal,
|
|
4449
|
+
await this.assertNoEscape(rootReal, path10.dirname(targetPath));
|
|
4354
4450
|
await this.assertNoEscape(rootReal, targetPath);
|
|
4355
4451
|
await this.assertFusionDirNotSymlinked();
|
|
4356
4452
|
}
|
|
@@ -4364,7 +4460,7 @@ var FusionArtifactStore = class {
|
|
|
4364
4460
|
* (a fresh write creates a real directory lexically under the root).
|
|
4365
4461
|
*/
|
|
4366
4462
|
async assertFusionDirNotSymlinked() {
|
|
4367
|
-
const fusionDir =
|
|
4463
|
+
const fusionDir = path10.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4368
4464
|
let stat4;
|
|
4369
4465
|
try {
|
|
4370
4466
|
stat4 = await this.io.lstat(fusionDir);
|
|
@@ -4500,7 +4596,7 @@ function reconstructFusionInputs(date, dayTranscripts) {
|
|
|
4500
4596
|
|
|
4501
4597
|
// src/meetings/store.ts
|
|
4502
4598
|
import { createHash as createHash3 } from "crypto";
|
|
4503
|
-
import * as
|
|
4599
|
+
import * as path11 from "path";
|
|
4504
4600
|
var MEETINGS_DIR_NAME = "meetings";
|
|
4505
4601
|
var MEETING_KIND = "meeting";
|
|
4506
4602
|
var MEETING_FORMAT_VERSION = 1;
|
|
@@ -4669,7 +4765,7 @@ var MeetingRecordStore = class {
|
|
|
4669
4765
|
constructor(memoryDir, io) {
|
|
4670
4766
|
this.memoryDir = memoryDir;
|
|
4671
4767
|
this.io = io;
|
|
4672
|
-
this.meetingsDir =
|
|
4768
|
+
this.meetingsDir = path11.join(memoryDir, MEETINGS_DIR_NAME);
|
|
4673
4769
|
}
|
|
4674
4770
|
memoryDir;
|
|
4675
4771
|
io;
|
|
@@ -4685,7 +4781,7 @@ var MeetingRecordStore = class {
|
|
|
4685
4781
|
if (idDate !== date) {
|
|
4686
4782
|
throw new Error(`meeting id '${id}' does not belong to date '${date}'`);
|
|
4687
4783
|
}
|
|
4688
|
-
return
|
|
4784
|
+
return path11.join(this.meetingsDir, date, `${id}.md`);
|
|
4689
4785
|
}
|
|
4690
4786
|
/** Idempotently persist a record: skip the write when contentHash is unchanged. */
|
|
4691
4787
|
async saveMeetingRecord(record) {
|
|
@@ -4716,7 +4812,7 @@ var MeetingRecordStore = class {
|
|
|
4716
4812
|
if (!isValidTranscriptDate(date)) {
|
|
4717
4813
|
throw new Error(`invalid meeting date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
4718
4814
|
}
|
|
4719
|
-
const dayDir =
|
|
4815
|
+
const dayDir = path11.join(this.meetingsDir, date);
|
|
4720
4816
|
await this.assertPathContained(dayDir);
|
|
4721
4817
|
let entries;
|
|
4722
4818
|
try {
|
|
@@ -4784,10 +4880,10 @@ var MeetingRecordStore = class {
|
|
|
4784
4880
|
try {
|
|
4785
4881
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
4786
4882
|
} catch {
|
|
4787
|
-
rootReal =
|
|
4883
|
+
rootReal = path11.resolve(this.memoryDir);
|
|
4788
4884
|
}
|
|
4789
4885
|
await this.assertNoEscape(rootReal, this.meetingsDir);
|
|
4790
|
-
await this.assertNoEscape(rootReal,
|
|
4886
|
+
await this.assertNoEscape(rootReal, path11.dirname(targetPath));
|
|
4791
4887
|
await this.assertNoEscape(rootReal, targetPath);
|
|
4792
4888
|
await this.assertNotSymlink(this.meetingsDir, "directory");
|
|
4793
4889
|
const dayDir = this.dayDirWithin(targetPath);
|
|
@@ -4797,11 +4893,11 @@ var MeetingRecordStore = class {
|
|
|
4797
4893
|
/** The `<meetings>/<date>` directory on the path to `targetPath`, or null when
|
|
4798
4894
|
* `targetPath` is the meetings root itself. */
|
|
4799
4895
|
dayDirWithin(targetPath) {
|
|
4800
|
-
const rel =
|
|
4801
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
4802
|
-
const first = rel.split(
|
|
4896
|
+
const rel = path11.relative(this.meetingsDir, targetPath);
|
|
4897
|
+
if (rel === "" || rel.startsWith("..") || path11.isAbsolute(rel)) return null;
|
|
4898
|
+
const first = rel.split(path11.sep)[0];
|
|
4803
4899
|
if (first === void 0 || first.length === 0) return null;
|
|
4804
|
-
return
|
|
4900
|
+
return path11.join(this.meetingsDir, first);
|
|
4805
4901
|
}
|
|
4806
4902
|
async assertNotSymlink(target, kind) {
|
|
4807
4903
|
let stat4;
|
|
@@ -4812,7 +4908,7 @@ var MeetingRecordStore = class {
|
|
|
4812
4908
|
throw err;
|
|
4813
4909
|
}
|
|
4814
4910
|
if (stat4.isSymbolicLink) {
|
|
4815
|
-
const label =
|
|
4911
|
+
const label = path11.relative(this.memoryDir, target) || MEETINGS_DIR_NAME;
|
|
4816
4912
|
throw new Error(
|
|
4817
4913
|
`meetings ${kind} '${label}' is a symbolic link \u2014 refusing to follow it even when it resolves inside the memory dir (AGENTS.md pattern #3)`
|
|
4818
4914
|
);
|
|
@@ -4836,8 +4932,8 @@ var SORT_STR = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
|
4836
4932
|
|
|
4837
4933
|
// src/storage/buffer-session-files.ts
|
|
4838
4934
|
import { createHash as createHash4 } from "crypto";
|
|
4839
|
-
import { lstat as
|
|
4840
|
-
import
|
|
4935
|
+
import { lstat as lstat4, readdir as readdir4, unlink as unlink3 } from "fs/promises";
|
|
4936
|
+
import path12 from "path";
|
|
4841
4937
|
function isMissing(err) {
|
|
4842
4938
|
return err?.code === "ENOENT";
|
|
4843
4939
|
}
|
|
@@ -4880,10 +4976,10 @@ var BufferSessionFiles = class {
|
|
|
4880
4976
|
io;
|
|
4881
4977
|
dirVerified = false;
|
|
4882
4978
|
get dir() {
|
|
4883
|
-
return
|
|
4979
|
+
return path12.join(this.stateDir, "buffer");
|
|
4884
4980
|
}
|
|
4885
4981
|
fileFor(key) {
|
|
4886
|
-
return
|
|
4982
|
+
return path12.join(this.dir, bufferSessionFileName(key));
|
|
4887
4983
|
}
|
|
4888
4984
|
/**
|
|
4889
4985
|
* Refuse a symlinked buffer directory: following it would send buffered
|
|
@@ -4895,7 +4991,7 @@ var BufferSessionFiles = class {
|
|
|
4895
4991
|
if (this.dirVerified) return;
|
|
4896
4992
|
let stat4 = null;
|
|
4897
4993
|
try {
|
|
4898
|
-
stat4 = await
|
|
4994
|
+
stat4 = await lstat4(this.dir);
|
|
4899
4995
|
} catch (err) {
|
|
4900
4996
|
if (!(err instanceof Error) || !isMissing(asFsError(err))) throw err;
|
|
4901
4997
|
}
|
|
@@ -4936,7 +5032,7 @@ var BufferSessionFiles = class {
|
|
|
4936
5032
|
const entries = /* @__PURE__ */ new Map();
|
|
4937
5033
|
for (const name of names) {
|
|
4938
5034
|
try {
|
|
4939
|
-
const body = JSON.parse(await this.io.read(
|
|
5035
|
+
const body = JSON.parse(await this.io.read(path12.join(this.dir, name)));
|
|
4940
5036
|
const parsed = entryFromBody(body);
|
|
4941
5037
|
if (!parsed) throw new Error("invalid buffer session file shape");
|
|
4942
5038
|
if (entries.has(parsed.key)) {
|
|
@@ -4960,7 +5056,7 @@ var BufferSessionFiles = class {
|
|
|
4960
5056
|
async readLegacy(hasSessionFiles) {
|
|
4961
5057
|
let raw;
|
|
4962
5058
|
try {
|
|
4963
|
-
raw = await this.io.read(
|
|
5059
|
+
raw = await this.io.read(path12.join(this.stateDir, "buffer.json"));
|
|
4964
5060
|
} catch (err) {
|
|
4965
5061
|
if (err instanceof SecureStoreLockedError) throw err;
|
|
4966
5062
|
if (err instanceof Error && isMissing(asFsError(err))) return null;
|
|
@@ -4993,7 +5089,7 @@ var BufferSessionFiles = class {
|
|
|
4993
5089
|
await this.save(key, entry);
|
|
4994
5090
|
}
|
|
4995
5091
|
try {
|
|
4996
|
-
await unlink3(
|
|
5092
|
+
await unlink3(path12.join(this.stateDir, "buffer.json"));
|
|
4997
5093
|
} catch (err) {
|
|
4998
5094
|
if (!(err instanceof Error) || !isMissing(asFsError(err))) throw err;
|
|
4999
5095
|
}
|
|
@@ -5022,7 +5118,7 @@ var BufferSessionFiles = class {
|
|
|
5022
5118
|
for (const name of existing) {
|
|
5023
5119
|
if (live.has(name)) continue;
|
|
5024
5120
|
try {
|
|
5025
|
-
await unlink3(
|
|
5121
|
+
await unlink3(path12.join(this.dir, name));
|
|
5026
5122
|
} catch (err) {
|
|
5027
5123
|
if (!(err instanceof Error) || !isMissing(asFsError(err))) throw err;
|
|
5028
5124
|
}
|
|
@@ -5032,7 +5128,7 @@ var BufferSessionFiles = class {
|
|
|
5032
5128
|
|
|
5033
5129
|
// src/storage/supersession-audit.ts
|
|
5034
5130
|
import { readdir as readdir5 } from "fs/promises";
|
|
5035
|
-
import
|
|
5131
|
+
import path13 from "path";
|
|
5036
5132
|
async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody, structuredAttributes) {
|
|
5037
5133
|
let entries;
|
|
5038
5134
|
try {
|
|
@@ -5044,7 +5140,7 @@ async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody,
|
|
|
5044
5140
|
for (const entry of entries) {
|
|
5045
5141
|
if (isMacOsReplicationJunkBasename(entry.name)) continue;
|
|
5046
5142
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
5047
|
-
const memory = await lookup.readMemoryByPath(
|
|
5143
|
+
const memory = await lookup.readMemoryByPath(path13.join(lookup.correctionsDir, entry.name));
|
|
5048
5144
|
if (memory?.frontmatter.category === "correction" && (memory.frontmatter.sourceMemoryId === oldMemoryId || memory.frontmatter.sourceMemoryId === void 0 && memory.frontmatter.lineage?.includes(oldMemoryId)) && memory.frontmatter.lineage?.includes(newMemoryId) && stripAttributesSuffix(memory.content) === auditBody && (structuredAttributes === void 0 || Object.entries(structuredAttributes).every(
|
|
5049
5145
|
([key, value]) => memory.frontmatter.structuredAttributes?.[key] === value
|
|
5050
5146
|
))) {
|
|
@@ -5136,12 +5232,12 @@ Reason: ${reason}`;
|
|
|
5136
5232
|
// src/storage/dropped-extraction-chunk.ts
|
|
5137
5233
|
import { randomUUID } from "crypto";
|
|
5138
5234
|
import { mkdir } from "fs/promises";
|
|
5139
|
-
import
|
|
5235
|
+
import path14 from "path";
|
|
5140
5236
|
async function saveDroppedExtractionChunk(stateDir, writeSecureFile, bufferKey, reason, turns) {
|
|
5141
|
-
const droppedDir =
|
|
5237
|
+
const droppedDir = path14.join(stateDir, "dropped");
|
|
5142
5238
|
await mkdir(droppedDir, { recursive: true });
|
|
5143
5239
|
const safeKey = bufferKey.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 80) || "default";
|
|
5144
|
-
const filePath =
|
|
5240
|
+
const filePath = path14.join(droppedDir, `${Date.now()}-${randomUUID().slice(0, 8)}-${safeKey}.json`);
|
|
5145
5241
|
const payload = { bufferKey, reason, droppedAt: (/* @__PURE__ */ new Date()).toISOString(), turns };
|
|
5146
5242
|
await writeSecureFile(filePath, JSON.stringify(payload, null, 2));
|
|
5147
5243
|
return filePath;
|
|
@@ -6147,17 +6243,17 @@ function inferEntityTypeFromContent(content) {
|
|
|
6147
6243
|
}
|
|
6148
6244
|
var KNOWN_ENTITY_FILENAME_PREFIXES = /* @__PURE__ */ new Set(["company", "other", "person", "place", "project", "tool", "topic"]);
|
|
6149
6245
|
function inferEntityTypeFromFilename(pathRel) {
|
|
6150
|
-
const basename =
|
|
6246
|
+
const basename = path15.basename(pathRel, ".md").toLowerCase();
|
|
6151
6247
|
const separator = basename.indexOf("-");
|
|
6152
6248
|
if (separator <= 0) return void 0;
|
|
6153
6249
|
const candidate = basename.slice(0, separator);
|
|
6154
6250
|
return KNOWN_ENTITY_FILENAME_PREFIXES.has(candidate) ? candidate : void 0;
|
|
6155
6251
|
}
|
|
6156
6252
|
function normalizeFrontmatterForPath(frontmatter, pathRel, content = "") {
|
|
6157
|
-
const normalizedPath = pathRel.split(
|
|
6253
|
+
const normalizedPath = pathRel.split(path15.sep).join("/");
|
|
6158
6254
|
let normalizedFrontmatter = frontmatter;
|
|
6159
6255
|
if (normalizedPath === "entities" || normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/")) {
|
|
6160
|
-
const basename =
|
|
6256
|
+
const basename = path15.basename(pathRel, ".md");
|
|
6161
6257
|
const inferredType = inferEntityTypeFromContent(content) || inferEntityTypeFromFilename(pathRel) || "entity";
|
|
6162
6258
|
const existingTags = Array.isArray(frontmatter.tags) ? frontmatter.tags : [];
|
|
6163
6259
|
normalizedFrontmatter = {
|
|
@@ -6630,9 +6726,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6630
6726
|
this.entitySchemas = entitySchemas;
|
|
6631
6727
|
this.deletionRevisionStore = new DeletionRevisionStore({
|
|
6632
6728
|
baseDir,
|
|
6633
|
-
deletionRevisionMetadataPath:
|
|
6634
|
-
invalidationCommitMetadataPath:
|
|
6635
|
-
deletionRevisionLockPath:
|
|
6729
|
+
deletionRevisionMetadataPath: path15.join(baseDir, ".offline-sync", "deletion-revisions.v1.json"),
|
|
6730
|
+
invalidationCommitMetadataPath: path15.join(baseDir, ".offline-sync", "invalidation-commits.v1.json"),
|
|
6731
|
+
deletionRevisionLockPath: path15.join(baseDir, ".offline-sync", "deletion-revisions.v1.json.lock"),
|
|
6636
6732
|
assertManagedStoragePath: (filePath, method) => this.assertManagedStoragePath(filePath, method)
|
|
6637
6733
|
});
|
|
6638
6734
|
this.casRevisions = new CasRevisionHost(baseDir);
|
|
@@ -6786,6 +6882,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6786
6882
|
onCatalogWrite;
|
|
6787
6883
|
/** Post-write embedding hook (#2019). Installed by the orchestrator; fire-and-forget. */
|
|
6788
6884
|
onMemoryWrite;
|
|
6885
|
+
/** Request search maintenance after a completed entity replay. */
|
|
6886
|
+
onEntityMigrationComplete;
|
|
6789
6887
|
notifyMemoryWrite(filePath) {
|
|
6790
6888
|
try {
|
|
6791
6889
|
this.onMemoryWrite?.(filePath);
|
|
@@ -6818,8 +6916,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6818
6916
|
}
|
|
6819
6917
|
/** Whether `filePath` resolves to `stateDir` itself or a path contained in it. */
|
|
6820
6918
|
isStateFilePath(filePath) {
|
|
6821
|
-
const rel =
|
|
6822
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
6919
|
+
const rel = path15.relative(this.stateDir, path15.resolve(filePath));
|
|
6920
|
+
return rel === "" || !rel.startsWith("..") && !path15.isAbsolute(rel);
|
|
6823
6921
|
}
|
|
6824
6922
|
// ── Tombstone store (issue #1579) ───────────────────────────────────────
|
|
6825
6923
|
// Instance-scoped (rule 11) + namespace-scoped (rule 42) tombstone index.
|
|
@@ -6934,8 +7032,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6934
7032
|
* /srv/cold/remnic), skipping the patch and stranding a stale hot entry.
|
|
6935
7033
|
*/
|
|
6936
7034
|
isColdOrArchiveTierPath(p) {
|
|
6937
|
-
const rel =
|
|
6938
|
-
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${
|
|
7035
|
+
const rel = path15.relative(this.baseDir, p);
|
|
7036
|
+
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${path15.sep}`) || rel.startsWith(`archive${path15.sep}`);
|
|
6939
7037
|
}
|
|
6940
7038
|
/**
|
|
6941
7039
|
* Mark the secure-store as required for this storage instance.
|
|
@@ -7022,7 +7120,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7022
7120
|
void 0,
|
|
7023
7121
|
this.baseDir
|
|
7024
7122
|
);
|
|
7025
|
-
const rel =
|
|
7123
|
+
const rel = path15.relative(this.baseDir, filePath).split(path15.sep).join("/");
|
|
7026
7124
|
return `${rel}:${version.versionId}`;
|
|
7027
7125
|
} catch (err) {
|
|
7028
7126
|
log.warn(
|
|
@@ -7067,10 +7165,10 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7067
7165
|
_StorageManager.okfConformanceByDir.set(memoryDir, enabled !== false);
|
|
7068
7166
|
}
|
|
7069
7167
|
okfConformanceEnabled() {
|
|
7070
|
-
for (let dir = this.baseDir; ; dir =
|
|
7168
|
+
for (let dir = this.baseDir; ; dir = path15.dirname(dir)) {
|
|
7071
7169
|
const registered = _StorageManager.okfConformanceByDir.get(dir);
|
|
7072
7170
|
if (registered !== void 0) return registered;
|
|
7073
|
-
if (dir ===
|
|
7171
|
+
if (dir === path15.dirname(dir)) return true;
|
|
7074
7172
|
}
|
|
7075
7173
|
}
|
|
7076
7174
|
/**
|
|
@@ -7114,12 +7212,12 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7114
7212
|
}
|
|
7115
7213
|
identityFilePath(workspaceDir, namespace) {
|
|
7116
7214
|
const rawNamespace = typeof namespace === "string" ? namespace.trim() : "";
|
|
7117
|
-
if (!rawNamespace) return
|
|
7215
|
+
if (!rawNamespace) return path15.join(workspaceDir, "IDENTITY.md");
|
|
7118
7216
|
const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
7119
|
-
return
|
|
7217
|
+
return path15.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);
|
|
7120
7218
|
}
|
|
7121
7219
|
versionFilePath(kind) {
|
|
7122
|
-
return
|
|
7220
|
+
return path15.join(this.stateDir, `.${kind}-version.log`);
|
|
7123
7221
|
}
|
|
7124
7222
|
bumpSharedVersion(kind, fallbackMap) {
|
|
7125
7223
|
const filePath = this.versionFilePath(kind);
|
|
@@ -7226,7 +7324,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7226
7324
|
// memories.
|
|
7227
7325
|
// -------------------------------------------------------------------------
|
|
7228
7326
|
get wearablesDir() {
|
|
7229
|
-
return
|
|
7327
|
+
return path15.join(this.baseDir, WEARABLES_DIR_NAME);
|
|
7230
7328
|
}
|
|
7231
7329
|
/**
|
|
7232
7330
|
* Resolve the on-disk path for a source/day transcript. Throws on
|
|
@@ -7242,7 +7340,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7242
7340
|
if (!isValidTranscriptDate(date)) {
|
|
7243
7341
|
throw new Error(`invalid wearable transcript date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
7244
7342
|
}
|
|
7245
|
-
return
|
|
7343
|
+
return path15.join(this.wearablesDir, sourceId, `${date}.md`);
|
|
7246
7344
|
}
|
|
7247
7345
|
async writeWearableDayTranscript(sourceId, date, serialized) {
|
|
7248
7346
|
const targetPath = this.wearableTranscriptPath(sourceId, date);
|
|
@@ -7271,7 +7369,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7271
7369
|
readDir: (d) => readdir6(d),
|
|
7272
7370
|
deleteFile: (p) => unlink4(p),
|
|
7273
7371
|
realpath: (p) => realpath3(p),
|
|
7274
|
-
lstat: (p) =>
|
|
7372
|
+
lstat: (p) => lstat5(p).then((st) => ({ isSymbolicLink: st.isSymbolicLink() }))
|
|
7275
7373
|
});
|
|
7276
7374
|
}
|
|
7277
7375
|
_meetingRecordStore;
|
|
@@ -7289,7 +7387,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7289
7387
|
readDir: (d) => readdir6(d),
|
|
7290
7388
|
deleteFile: (p) => unlink4(p),
|
|
7291
7389
|
realpath: (p) => realpath3(p),
|
|
7292
|
-
lstat: (p) =>
|
|
7390
|
+
lstat: (p) => lstat5(p).then((st) => ({ isSymbolicLink: st.isSymbolicLink() }))
|
|
7293
7391
|
});
|
|
7294
7392
|
}
|
|
7295
7393
|
/**
|
|
@@ -7356,25 +7454,25 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7356
7454
|
});
|
|
7357
7455
|
}
|
|
7358
7456
|
get factsDir() {
|
|
7359
|
-
return
|
|
7457
|
+
return path15.join(this.baseDir, "facts");
|
|
7360
7458
|
}
|
|
7361
7459
|
get correctionsDir() {
|
|
7362
|
-
return
|
|
7460
|
+
return path15.join(this.baseDir, "corrections");
|
|
7363
7461
|
}
|
|
7364
7462
|
get proceduresDir() {
|
|
7365
|
-
return
|
|
7463
|
+
return path15.join(this.baseDir, "procedures");
|
|
7366
7464
|
}
|
|
7367
7465
|
get reasoningTracesDir() {
|
|
7368
|
-
return
|
|
7466
|
+
return path15.join(this.baseDir, "reasoning-traces");
|
|
7369
7467
|
}
|
|
7370
7468
|
get entitiesDir() {
|
|
7371
|
-
return
|
|
7469
|
+
return path15.join(this.baseDir, "entities");
|
|
7372
7470
|
}
|
|
7373
7471
|
resolveEntityFilePath(name) {
|
|
7374
7472
|
if (typeof name !== "string") return null;
|
|
7375
|
-
const filePath =
|
|
7376
|
-
const relative2 =
|
|
7377
|
-
if (relative2 === "" || relative2.startsWith("..") ||
|
|
7473
|
+
const filePath = path15.resolve(this.entitiesDir, `${name}.md`);
|
|
7474
|
+
const relative2 = path15.relative(this.entitiesDir, filePath);
|
|
7475
|
+
if (relative2 === "" || relative2.startsWith("..") || path15.isAbsolute(relative2)) {
|
|
7378
7476
|
return null;
|
|
7379
7477
|
}
|
|
7380
7478
|
return filePath;
|
|
@@ -7385,7 +7483,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7385
7483
|
async readDependencyPropagationQueueFile(filePath) {
|
|
7386
7484
|
const target = await resolveSafeStoragePath(
|
|
7387
7485
|
this.baseDir,
|
|
7388
|
-
|
|
7486
|
+
path15.relative(
|
|
7389
7487
|
this.baseDir,
|
|
7390
7488
|
this.assertManagedStoragePath(filePath, "storage.readDependencyPropagationQueueFile")
|
|
7391
7489
|
)
|
|
@@ -7395,7 +7493,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7395
7493
|
async writeDependencyPropagationQueueFile(filePath, content) {
|
|
7396
7494
|
const target = await resolveSafeStoragePath(
|
|
7397
7495
|
this.baseDir,
|
|
7398
|
-
|
|
7496
|
+
path15.relative(
|
|
7399
7497
|
this.baseDir,
|
|
7400
7498
|
this.assertManagedStoragePath(filePath, "storage.writeDependencyPropagationQueueFile")
|
|
7401
7499
|
)
|
|
@@ -7410,10 +7508,10 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7410
7508
|
});
|
|
7411
7509
|
}
|
|
7412
7510
|
assertManagedStoragePath(filePath, method) {
|
|
7413
|
-
const resolved =
|
|
7414
|
-
const base =
|
|
7415
|
-
const rel =
|
|
7416
|
-
if (rel === "" || rel === ".." || rel.startsWith(`..${
|
|
7511
|
+
const resolved = path15.resolve(filePath);
|
|
7512
|
+
const base = path15.resolve(this.baseDir);
|
|
7513
|
+
const rel = path15.relative(base, resolved);
|
|
7514
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${path15.sep}`) || path15.isAbsolute(rel)) {
|
|
7417
7515
|
throw new Error(`${method}: file path escapes memory dir`);
|
|
7418
7516
|
}
|
|
7419
7517
|
return resolved;
|
|
@@ -7450,7 +7548,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7450
7548
|
async digestOfflineSyncFile(filePath) {
|
|
7451
7549
|
const target = this.assertManagedStoragePath(filePath, "storage.digestOfflineSyncFile");
|
|
7452
7550
|
const st = await stat3(target);
|
|
7453
|
-
const relPath =
|
|
7551
|
+
const relPath = path15.relative(this.baseDir, target).split(path15.sep).join("/");
|
|
7454
7552
|
const cache = await this.loadOfflineSyncDigestCache();
|
|
7455
7553
|
const cached = cache.get(relPath);
|
|
7456
7554
|
if (cached && cached.statBytes === st.size && cached.mtimeMs === st.mtimeMs && cached.ctimeMs === st.ctimeMs && !cached.encrypted) {
|
|
@@ -7535,7 +7633,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7535
7633
|
const cache = this.offlineSyncDigestCache;
|
|
7536
7634
|
if (!cache) return;
|
|
7537
7635
|
const entries = [...cache.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([entryPath, entry]) => ({ path: entryPath, ...entry }));
|
|
7538
|
-
await mkdir2(
|
|
7636
|
+
await mkdir2(path15.dirname(this.offlineSyncDigestCachePath), { recursive: true });
|
|
7539
7637
|
await writeFile(this.offlineSyncDigestCachePath, `${JSON.stringify({ version: 1, entries })}
|
|
7540
7638
|
`, "utf-8");
|
|
7541
7639
|
}).catch((err) => {
|
|
@@ -7636,7 +7734,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7636
7734
|
}
|
|
7637
7735
|
async appendStorageSecureFileUnlocked(filePath, content) {
|
|
7638
7736
|
const writeKey = this.resolveWriteKey();
|
|
7639
|
-
await mkdir2(
|
|
7737
|
+
await mkdir2(path15.dirname(filePath), { recursive: true });
|
|
7640
7738
|
if (writeKey === null) {
|
|
7641
7739
|
try {
|
|
7642
7740
|
if (await this.isEncryptedFileHeader(filePath)) {
|
|
@@ -7662,13 +7760,13 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7662
7760
|
this.notifyCatalogWriteForPath(filePath);
|
|
7663
7761
|
}
|
|
7664
7762
|
get stateDir() {
|
|
7665
|
-
return
|
|
7763
|
+
return path15.join(this.baseDir, "state");
|
|
7666
7764
|
}
|
|
7667
7765
|
get offlineSyncDigestCachePath() {
|
|
7668
|
-
return
|
|
7766
|
+
return path15.join(this.baseDir, ".offline-sync", "digest-cache.v1.json");
|
|
7669
7767
|
}
|
|
7670
7768
|
get entitySynthesisQueuePath() {
|
|
7671
|
-
return
|
|
7769
|
+
return path15.join(this.stateDir, "entity-synthesis-queue.json");
|
|
7672
7770
|
}
|
|
7673
7771
|
// ── Tombstone store access (issue #1579) ─────────────────────────────────
|
|
7674
7772
|
/**
|
|
@@ -7678,7 +7776,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7678
7776
|
* helpers are injected into the store).
|
|
7679
7777
|
*/
|
|
7680
7778
|
get tombstonesPath() {
|
|
7681
|
-
return
|
|
7779
|
+
return path15.join(this.stateDir, "tombstones.jsonl");
|
|
7682
7780
|
}
|
|
7683
7781
|
/**
|
|
7684
7782
|
* Configure the tombstone invariant for this storage instance. Installed
|
|
@@ -7857,7 +7955,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7857
7955
|
* resolves to the legacy short bounds instead of the converge deadline.
|
|
7858
7956
|
*/
|
|
7859
7957
|
captureLockLimitSource() {
|
|
7860
|
-
const options = this.factHashIndexLockOptions;
|
|
7958
|
+
const options = { ...this.factHashIndexLockOptions, ...scopedCaptureWriteLockLimits(this) };
|
|
7861
7959
|
const keys = ["captureWriteLockInitialDelayMs", "captureWriteLockMaxDelayMs", "captureWriteLockDeadlineMs", "captureWriteLockSignal"];
|
|
7862
7960
|
return keys.some((key) => options[key] !== void 0) ? options : void 0;
|
|
7863
7961
|
}
|
|
@@ -7991,55 +8089,55 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7991
8089
|
return legacyMatches.length > 0 ? [...new Set(legacyMatches.map((content) => ContentHashIndex.computeHash(content)))] : [persistedHash];
|
|
7992
8090
|
}
|
|
7993
8091
|
get questionsDir() {
|
|
7994
|
-
return
|
|
8092
|
+
return path15.join(this.baseDir, "questions");
|
|
7995
8093
|
}
|
|
7996
8094
|
get artifactsDir() {
|
|
7997
|
-
return
|
|
8095
|
+
return path15.join(this.baseDir, "artifacts");
|
|
7998
8096
|
}
|
|
7999
8097
|
get identityDir() {
|
|
8000
|
-
return
|
|
8098
|
+
return path15.join(this.baseDir, "identity");
|
|
8001
8099
|
}
|
|
8002
8100
|
get identityAnchorPath() {
|
|
8003
|
-
return
|
|
8101
|
+
return path15.join(this.identityDir, "identity-anchor.md");
|
|
8004
8102
|
}
|
|
8005
8103
|
get identityIncidentsDir() {
|
|
8006
|
-
return
|
|
8104
|
+
return path15.join(this.identityDir, "incidents");
|
|
8007
8105
|
}
|
|
8008
8106
|
get identityAuditsWeeklyDir() {
|
|
8009
|
-
return
|
|
8107
|
+
return path15.join(this.identityDir, "audits", "weekly");
|
|
8010
8108
|
}
|
|
8011
8109
|
get identityAuditsMonthlyDir() {
|
|
8012
|
-
return
|
|
8110
|
+
return path15.join(this.identityDir, "audits", "monthly");
|
|
8013
8111
|
}
|
|
8014
8112
|
get identityImprovementLoopsPath() {
|
|
8015
|
-
return
|
|
8113
|
+
return path15.join(this.identityDir, "improvement-loops.md");
|
|
8016
8114
|
}
|
|
8017
8115
|
get identityReflectionsPath() {
|
|
8018
|
-
return
|
|
8116
|
+
return path15.join(this.identityDir, "reflections.md");
|
|
8019
8117
|
}
|
|
8020
8118
|
get profilePath() {
|
|
8021
|
-
return
|
|
8119
|
+
return path15.join(this.baseDir, "profile.md");
|
|
8022
8120
|
}
|
|
8023
8121
|
get memoryActionsPath() {
|
|
8024
|
-
return
|
|
8122
|
+
return path15.join(this.stateDir, "memory-actions.jsonl");
|
|
8025
8123
|
}
|
|
8026
8124
|
get memoryLifecycleLedgerPath() {
|
|
8027
|
-
return
|
|
8125
|
+
return path15.join(this.stateDir, "memory-lifecycle-ledger.jsonl");
|
|
8028
8126
|
}
|
|
8029
8127
|
get compressionGuidelinesPath() {
|
|
8030
|
-
return
|
|
8128
|
+
return path15.join(this.stateDir, "compression-guidelines.md");
|
|
8031
8129
|
}
|
|
8032
8130
|
get compressionGuidelineDraftPath() {
|
|
8033
|
-
return
|
|
8131
|
+
return path15.join(this.stateDir, "compression-guidelines.draft.md");
|
|
8034
8132
|
}
|
|
8035
8133
|
get compressionGuidelineStatePath() {
|
|
8036
|
-
return
|
|
8134
|
+
return path15.join(this.stateDir, "compression-guideline-state.json");
|
|
8037
8135
|
}
|
|
8038
8136
|
get compressionGuidelineDraftStatePath() {
|
|
8039
|
-
return
|
|
8137
|
+
return path15.join(this.stateDir, "compression-guideline-draft-state.json");
|
|
8040
8138
|
}
|
|
8041
8139
|
get behaviorSignalsPath() {
|
|
8042
|
-
return
|
|
8140
|
+
return path15.join(this.stateDir, "behavior-signals.jsonl");
|
|
8043
8141
|
}
|
|
8044
8142
|
/**
|
|
8045
8143
|
* In-memory dedup key set for behavior-signals appends (issue #1909),
|
|
@@ -8071,7 +8169,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8071
8169
|
* governance sweeps can treat it uniformly.
|
|
8072
8170
|
*/
|
|
8073
8171
|
get bufferSurpriseLedgerPath() {
|
|
8074
|
-
return
|
|
8172
|
+
return path15.join(this.stateDir, "buffer-surprise-ledger.jsonl");
|
|
8075
8173
|
}
|
|
8076
8174
|
/**
|
|
8077
8175
|
* Entity alias table loaded from THIS store's config/aliases.json.
|
|
@@ -8134,7 +8232,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8134
8232
|
this.loadAliasesSync();
|
|
8135
8233
|
}
|
|
8136
8234
|
loadAliasesSync() {
|
|
8137
|
-
const aliasPath =
|
|
8235
|
+
const aliasPath = path15.join(this.baseDir, "config", "aliases.json");
|
|
8138
8236
|
this.userAliases = {};
|
|
8139
8237
|
const raw = readEntityAliasConfigSync(this.baseDir);
|
|
8140
8238
|
if (raw === void 0) return;
|
|
@@ -8172,9 +8270,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8172
8270
|
await mkdir2(this.baseDir, { recursive: true });
|
|
8173
8271
|
await validateRoots(this.baseDir, this.entitiesDir, this.stateDir, this.archiveDir);
|
|
8174
8272
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8175
|
-
await mkdir2(
|
|
8176
|
-
await mkdir2(
|
|
8177
|
-
await mkdir2(
|
|
8273
|
+
await mkdir2(path15.join(this.factsDir, today), { recursive: true });
|
|
8274
|
+
await mkdir2(path15.join(this.proceduresDir, today), { recursive: true });
|
|
8275
|
+
await mkdir2(path15.join(this.reasoningTracesDir, today), { recursive: true });
|
|
8178
8276
|
await mkdir2(this.correctionsDir, { recursive: true });
|
|
8179
8277
|
await mkdir2(this.entitiesDir, { recursive: true });
|
|
8180
8278
|
await mkdir2(this.stateDir, { recursive: true });
|
|
@@ -8184,7 +8282,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8184
8282
|
await mkdir2(this.identityIncidentsDir, { recursive: true });
|
|
8185
8283
|
await mkdir2(this.identityAuditsWeeklyDir, { recursive: true });
|
|
8186
8284
|
await mkdir2(this.identityAuditsMonthlyDir, { recursive: true });
|
|
8187
|
-
await mkdir2(
|
|
8285
|
+
await mkdir2(path15.join(this.baseDir, "config"), { recursive: true });
|
|
8188
8286
|
await this.entityCanonicalIdMigration.begin(options.waitForEntityMigration !== false, this.entitiesDir);
|
|
8189
8287
|
if (this.hotMemoriesCacheEnabled && this.getMemoryCorpusVersion() === 0) {
|
|
8190
8288
|
this.bumpMemoryCorpusVersion();
|
|
@@ -8207,11 +8305,11 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8207
8305
|
async resolveCategoryWritePath(category, id, today) {
|
|
8208
8306
|
if (category === "correction") {
|
|
8209
8307
|
await mkdir2(this.correctionsDir, { recursive: true });
|
|
8210
|
-
return
|
|
8308
|
+
return path15.join(this.correctionsDir, `${id}.md`);
|
|
8211
8309
|
}
|
|
8212
|
-
const datedDir =
|
|
8310
|
+
const datedDir = path15.join(getCategoryDir(this.baseDir, category), today);
|
|
8213
8311
|
await mkdir2(datedDir, { recursive: true });
|
|
8214
|
-
return
|
|
8312
|
+
return path15.join(datedDir, `${id}.md`);
|
|
8215
8313
|
}
|
|
8216
8314
|
async findExistingTombstoneBlockedMemory(content, category, sourceConnector) {
|
|
8217
8315
|
const identity = buildExplicitCaptureDedupKey(content, category, sourceConnector);
|
|
@@ -8590,7 +8688,7 @@ ${sanitized.text}
|
|
|
8590
8688
|
await this.ensureDirectories();
|
|
8591
8689
|
const now = /* @__PURE__ */ new Date();
|
|
8592
8690
|
const day = now.toISOString().slice(0, 10);
|
|
8593
|
-
const dir =
|
|
8691
|
+
const dir = path15.join(this.artifactsDir, day);
|
|
8594
8692
|
await mkdir2(dir, { recursive: true });
|
|
8595
8693
|
const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
8596
8694
|
const fm = {
|
|
@@ -8617,7 +8715,7 @@ ${sanitized.text}
|
|
|
8617
8715
|
log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
8618
8716
|
return "";
|
|
8619
8717
|
}
|
|
8620
|
-
const filePath =
|
|
8718
|
+
const filePath = path15.join(dir, `${id}.md`);
|
|
8621
8719
|
await this.writeStorageSecureFile(filePath, `${serializeFrontmatter(this.withOkfType(fm))}
|
|
8622
8720
|
|
|
8623
8721
|
${sanitized.text}
|
|
@@ -8911,7 +9009,7 @@ ${sanitized.text}
|
|
|
8911
9009
|
* per-process in-memory cache safe across process boundaries.
|
|
8912
9010
|
*/
|
|
8913
9011
|
invalidateColdMemoriesCache() {
|
|
8914
|
-
const coldRoot =
|
|
9012
|
+
const coldRoot = path15.join(this.baseDir, "cold");
|
|
8915
9013
|
_StorageManager.coldMemoriesCache.delete(coldRoot);
|
|
8916
9014
|
this.bumpColdWriteVersion();
|
|
8917
9015
|
invalidateAllForDir(this.baseDir);
|
|
@@ -9029,7 +9127,7 @@ ${sanitized.text}
|
|
|
9029
9127
|
const correctionPaths = [];
|
|
9030
9128
|
const factPaths = [];
|
|
9031
9129
|
for (const filePath of filePaths) {
|
|
9032
|
-
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${
|
|
9130
|
+
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${path15.sep}`)) {
|
|
9033
9131
|
correctionPaths.push(filePath);
|
|
9034
9132
|
} else {
|
|
9035
9133
|
factPaths.push(filePath);
|
|
@@ -9049,11 +9147,12 @@ ${sanitized.text}
|
|
|
9049
9147
|
}
|
|
9050
9148
|
return ordered;
|
|
9051
9149
|
}
|
|
9052
|
-
async readWindowBoundedBatch(candidateBatchPaths, remainingSlots, remainingInspectionBudget, readBatchSize) {
|
|
9150
|
+
async readWindowBoundedBatch(candidateBatchPaths, remainingSlots, remainingInspectionBudget, readBatchSize, options) {
|
|
9053
9151
|
const memories = [];
|
|
9054
9152
|
const filePaths = [];
|
|
9055
9153
|
const normalizedReadBatchSize = this.normalizeMemoryReadBatchSize(readBatchSize);
|
|
9056
9154
|
for (let index = 0; index < candidateBatchPaths.length; ) {
|
|
9155
|
+
checkCorpusReadAbort(options);
|
|
9057
9156
|
if (memories.length >= remainingSlots || filePaths.length >= remainingInspectionBudget) break;
|
|
9058
9157
|
const availableSlots = remainingSlots - memories.length;
|
|
9059
9158
|
const availableInspectionBudget = remainingInspectionBudget - filePaths.length;
|
|
@@ -9065,7 +9164,7 @@ ${sanitized.text}
|
|
|
9065
9164
|
index += candidatePaths.length;
|
|
9066
9165
|
if (candidatePaths.length === 0) break;
|
|
9067
9166
|
filePaths.push(...candidatePaths);
|
|
9068
|
-
const parsedMemories = await this.readParsedMemoriesFromPaths(candidatePaths, candidatePaths.length);
|
|
9167
|
+
const parsedMemories = await this.readParsedMemoriesFromPaths(candidatePaths, candidatePaths.length, options);
|
|
9069
9168
|
if (parsedMemories.length === 0) continue;
|
|
9070
9169
|
memories.push(...parsedMemories.slice(0, availableSlots));
|
|
9071
9170
|
}
|
|
@@ -9095,7 +9194,7 @@ ${sanitized.text}
|
|
|
9095
9194
|
const entries = (await readdir6(dir, { withFileTypes: true })).filter((e) => !isMacOsReplicationJunkBasename(e.name));
|
|
9096
9195
|
for (const entry of entries) {
|
|
9097
9196
|
checkCorpusReadAbort(options);
|
|
9098
|
-
const fullPath =
|
|
9197
|
+
const fullPath = path15.join(dir, entry.name);
|
|
9099
9198
|
if (entry.isDirectory()) {
|
|
9100
9199
|
await readDir(fullPath);
|
|
9101
9200
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -9135,7 +9234,7 @@ ${sanitized.text}
|
|
|
9135
9234
|
return this.rememberMemorySnapshot(await this.memoryReadStore.readMemoryByPath(filePath));
|
|
9136
9235
|
}
|
|
9137
9236
|
resolveTierRootDir(tier) {
|
|
9138
|
-
return tier === "cold" ?
|
|
9237
|
+
return tier === "cold" ? path15.join(this.baseDir, "cold") : this.baseDir;
|
|
9139
9238
|
}
|
|
9140
9239
|
resolveMemoryDateDir(memory) {
|
|
9141
9240
|
const preferred = memory.frontmatter.created || memory.frontmatter.updated;
|
|
@@ -9150,13 +9249,13 @@ ${sanitized.text}
|
|
|
9150
9249
|
buildTierMemoryPath(memory, tier) {
|
|
9151
9250
|
const root = this.resolveTierRootDir(tier);
|
|
9152
9251
|
if (this.isArtifactMemory(memory)) {
|
|
9153
|
-
return
|
|
9252
|
+
return path15.join(root, "artifacts", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
9154
9253
|
}
|
|
9155
9254
|
if (memory.frontmatter.category === "correction") {
|
|
9156
|
-
return
|
|
9255
|
+
return path15.join(root, "corrections", `${memory.frontmatter.id}.md`);
|
|
9157
9256
|
}
|
|
9158
9257
|
const dir = categoryDirName(memory.frontmatter.category);
|
|
9159
|
-
return
|
|
9258
|
+
return path15.join(root, dir, this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
9160
9259
|
}
|
|
9161
9260
|
async writeMemoryFileAtomic(targetPath, memory) {
|
|
9162
9261
|
assertNotOkfReservedBasename(targetPath);
|
|
@@ -9235,8 +9334,8 @@ ${memory.content}
|
|
|
9235
9334
|
memory.frontmatter.entityRef = current.frontmatter.entityRef;
|
|
9236
9335
|
}
|
|
9237
9336
|
durable = true;
|
|
9238
|
-
const sourcePath =
|
|
9239
|
-
const destPath =
|
|
9337
|
+
const sourcePath = path15.resolve(current.path);
|
|
9338
|
+
const destPath = path15.resolve(targetPath);
|
|
9240
9339
|
if (sourcePath !== destPath) {
|
|
9241
9340
|
await recordArchiveDelete2(this.baseDir, current.path, () => this.deleteManagedStorageFile(current.path));
|
|
9242
9341
|
this.invalidateAllMemoriesCache();
|
|
@@ -9260,8 +9359,8 @@ ${memory.content}
|
|
|
9260
9359
|
}
|
|
9261
9360
|
async migrateMemoryToTier(memory, targetTier) {
|
|
9262
9361
|
const targetPath = this.buildTierMemoryPath(memory, targetTier);
|
|
9263
|
-
const sourcePath =
|
|
9264
|
-
const destPath =
|
|
9362
|
+
const sourcePath = path15.resolve(memory.path);
|
|
9363
|
+
const destPath = path15.resolve(targetPath);
|
|
9265
9364
|
if (sourcePath === destPath) {
|
|
9266
9365
|
return { changed: false, targetPath };
|
|
9267
9366
|
}
|
|
@@ -9271,7 +9370,7 @@ ${memory.content}
|
|
|
9271
9370
|
return { changed, targetPath };
|
|
9272
9371
|
}
|
|
9273
9372
|
get archiveDir() {
|
|
9274
|
-
return
|
|
9373
|
+
return path15.join(this.baseDir, "archive");
|
|
9275
9374
|
}
|
|
9276
9375
|
/**
|
|
9277
9376
|
* Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.
|
|
@@ -9284,7 +9383,7 @@ ${memory.content}
|
|
|
9284
9383
|
try {
|
|
9285
9384
|
const now = lifecycle?.at ?? /* @__PURE__ */ new Date();
|
|
9286
9385
|
const today = now.toISOString().slice(0, 10);
|
|
9287
|
-
const destDir =
|
|
9386
|
+
const destDir = path15.join(this.archiveDir, today);
|
|
9288
9387
|
await mkdir2(destDir, { recursive: true });
|
|
9289
9388
|
const refIdsAtWrite = this.currentHistoricalIds();
|
|
9290
9389
|
const updatedFm = canonicalizeEntityRefOption(
|
|
@@ -9300,7 +9399,7 @@ ${memory.content}
|
|
|
9300
9399
|
|
|
9301
9400
|
${current.content}
|
|
9302
9401
|
`;
|
|
9303
|
-
const destPath =
|
|
9402
|
+
const destPath = path15.join(destDir, path15.basename(current.path));
|
|
9304
9403
|
const priorDest = await this.readStorageSecureFile(destPath).catch(() => null);
|
|
9305
9404
|
await recordArchiveWrite(this.baseDir, destPath, () => this.writeStorageSecureFile(destPath, fileContent));
|
|
9306
9405
|
if (typeof current.frontmatter.entityRef === "string") {
|
|
@@ -9534,7 +9633,7 @@ ${memory.content}
|
|
|
9534
9633
|
`;
|
|
9535
9634
|
await this.writeTombstoneBlockedFrontmatter(memory, fileContent, updated, async () => {
|
|
9536
9635
|
this.invalidateAllMemoriesCache();
|
|
9537
|
-
if (memory.path.includes(`${
|
|
9636
|
+
if (memory.path.includes(`${path15.sep}cold${path15.sep}`)) {
|
|
9538
9637
|
this.invalidateColdMemoriesCache();
|
|
9539
9638
|
}
|
|
9540
9639
|
});
|
|
@@ -9546,7 +9645,7 @@ ${memory.content}
|
|
|
9546
9645
|
}
|
|
9547
9646
|
if (mentionReentry && !entityMentionEpoch.neutral(memory.frontmatter, updated)) entityMentionEpoch.bump(this.baseDir);
|
|
9548
9647
|
await this.patchHotMemoriesCache({ addedPath: memory.path });
|
|
9549
|
-
if (memory.path.includes(`${
|
|
9648
|
+
if (memory.path.includes(`${path15.sep}cold${path15.sep}`)) {
|
|
9550
9649
|
this.invalidateColdMemoriesCache();
|
|
9551
9650
|
}
|
|
9552
9651
|
try {
|
|
@@ -9648,7 +9747,7 @@ ${memory.content}
|
|
|
9648
9747
|
return saveDroppedExtractionChunk(this.stateDir, (file, content) => this.writeStorageSecureFile(file, content), bufferKey, reason, turns);
|
|
9649
9748
|
}
|
|
9650
9749
|
async loadMeta() {
|
|
9651
|
-
const metaPath =
|
|
9750
|
+
const metaPath = path15.join(this.stateDir, "meta.json");
|
|
9652
9751
|
try {
|
|
9653
9752
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
9654
9753
|
const parsed = JSON.parse(raw);
|
|
@@ -9681,7 +9780,7 @@ ${memory.content}
|
|
|
9681
9780
|
}
|
|
9682
9781
|
async saveMeta(state) {
|
|
9683
9782
|
await this.ensureDirectories();
|
|
9684
|
-
await this.writeStorageSecureFile(
|
|
9783
|
+
await this.writeStorageSecureFile(path15.join(this.stateDir, "meta.json"), JSON.stringify(state, null, 2));
|
|
9685
9784
|
}
|
|
9686
9785
|
async appendMemoryActionEvents(events) {
|
|
9687
9786
|
if (events.length === 0) return 0;
|
|
@@ -9750,7 +9849,7 @@ ${memory.content}
|
|
|
9750
9849
|
},
|
|
9751
9850
|
(payload) => this.appendStorageSecureFile(target, payload),
|
|
9752
9851
|
async () => {
|
|
9753
|
-
await mkdir2(
|
|
9852
|
+
await mkdir2(path15.dirname(target), { recursive: true });
|
|
9754
9853
|
}
|
|
9755
9854
|
);
|
|
9756
9855
|
}
|
|
@@ -9848,7 +9947,7 @@ ${memory.content}
|
|
|
9848
9947
|
async appendReextractJobs(events) {
|
|
9849
9948
|
if (events.length === 0) return 0;
|
|
9850
9949
|
await this.ensureDirectories();
|
|
9851
|
-
const filePath =
|
|
9950
|
+
const filePath = path15.join(this.stateDir, "reextract-jobs.jsonl");
|
|
9852
9951
|
const lines = events.map((event) => JSON.stringify(event)).join("\n") + "\n";
|
|
9853
9952
|
try {
|
|
9854
9953
|
await this.appendStorageSecureFile(filePath, lines);
|
|
@@ -9861,7 +9960,7 @@ ${memory.content}
|
|
|
9861
9960
|
}
|
|
9862
9961
|
async readReextractJobs(limit = 200) {
|
|
9863
9962
|
const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1e3, Math.floor(limit))) : 200;
|
|
9864
|
-
const filePath =
|
|
9963
|
+
const filePath = path15.join(this.stateDir, "reextract-jobs.jsonl");
|
|
9865
9964
|
try {
|
|
9866
9965
|
const raw = await this.readStorageSecureFile(filePath);
|
|
9867
9966
|
const lines = raw.split("\n").filter((line) => line.trim().length > 0);
|
|
@@ -10096,7 +10195,7 @@ ${question}
|
|
|
10096
10195
|
|
|
10097
10196
|
**Context:** ${context}
|
|
10098
10197
|
`;
|
|
10099
|
-
const filePath =
|
|
10198
|
+
const filePath = path15.join(this.questionsDir, `${id}.md`);
|
|
10100
10199
|
await this.writeStorageSecureFile(filePath, content);
|
|
10101
10200
|
log.debug(`wrote question ${id} to ${filePath}`);
|
|
10102
10201
|
this.invalidateQuestionsCache();
|
|
@@ -10155,11 +10254,11 @@ ${question}
|
|
|
10155
10254
|
} catch {
|
|
10156
10255
|
}
|
|
10157
10256
|
const hygiene = opts?.hygiene;
|
|
10158
|
-
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(
|
|
10257
|
+
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(path15.basename(identityPath));
|
|
10159
10258
|
if (rotateEnabled) {
|
|
10160
10259
|
const maxBytes = hygiene.rotateMaxBytes;
|
|
10161
10260
|
if (existing.length > maxBytes) {
|
|
10162
|
-
const archiveDir =
|
|
10261
|
+
const archiveDir = path15.join(workspaceDir, hygiene.archiveDir);
|
|
10163
10262
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
10164
10263
|
filePath: identityPath,
|
|
10165
10264
|
archiveDir,
|
|
@@ -10419,7 +10518,7 @@ ${reflection}
|
|
|
10419
10518
|
if (entries.length === 0) return 0;
|
|
10420
10519
|
const memories = await this.readAllMemories();
|
|
10421
10520
|
const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));
|
|
10422
|
-
const memoryPathMap = new Map(memories.map((m) => [
|
|
10521
|
+
const memoryPathMap = new Map(memories.map((m) => [path15.resolve(m.path), m]));
|
|
10423
10522
|
let updated = 0;
|
|
10424
10523
|
const prevVersion = this.getMemoryCorpusVersion();
|
|
10425
10524
|
let entityRefMoved = false;
|
|
@@ -10427,7 +10526,7 @@ ${reflection}
|
|
|
10427
10526
|
const warm = this.hotMemoriesCacheEnabled && getCachedMemories(this.baseDir, prevVersion, keyId, this.hotCacheTtlMs()) !== null;
|
|
10428
10527
|
const appliedPatches = /* @__PURE__ */ new Map();
|
|
10429
10528
|
for (const entry of entries) {
|
|
10430
|
-
const memory = entry.memoryPath ? memoryPathMap.get(
|
|
10529
|
+
const memory = entry.memoryPath ? memoryPathMap.get(path15.resolve(entry.memoryPath)) : memoryMap.get(entry.memoryId);
|
|
10431
10530
|
if (!memory) continue;
|
|
10432
10531
|
try {
|
|
10433
10532
|
const applied = await this.withTombstoneBlockedMemoryPathLock(memory.path, async (current) => {
|
|
@@ -10459,7 +10558,7 @@ ${current.content}
|
|
|
10459
10558
|
if (warm) {
|
|
10460
10559
|
updateCacheOnWrite(this.baseDir, { ...applied.current, frontmatter: applied.newFm }, keyId);
|
|
10461
10560
|
}
|
|
10462
|
-
appliedPatches.set(
|
|
10561
|
+
appliedPatches.set(path15.resolve(memory.path), {
|
|
10463
10562
|
accessCount: entry.newCount,
|
|
10464
10563
|
lastAccessed: entry.lastAccessed
|
|
10465
10564
|
});
|
|
@@ -10477,7 +10576,7 @@ ${current.content}
|
|
|
10477
10576
|
const cur = getCachedMemories(this.baseDir, prevVersion, keyId);
|
|
10478
10577
|
if (cur) {
|
|
10479
10578
|
const reapplied = cur.map((m) => {
|
|
10480
|
-
const patch = appliedPatches.get(
|
|
10579
|
+
const patch = appliedPatches.get(path15.resolve(m.path));
|
|
10481
10580
|
return patch ? {
|
|
10482
10581
|
...m,
|
|
10483
10582
|
frontmatter: { ...m.frontmatter, accessCount: patch.accessCount, lastAccessed: patch.lastAccessed }
|
|
@@ -10507,7 +10606,7 @@ ${current.content}
|
|
|
10507
10606
|
const pathsById = /* @__PURE__ */ new Map();
|
|
10508
10607
|
const filePathsById = /* @__PURE__ */ new Map();
|
|
10509
10608
|
for (const filePath of filePaths) {
|
|
10510
|
-
const memoryId =
|
|
10609
|
+
const memoryId = path15.basename(filePath, ".md");
|
|
10511
10610
|
if (!wantedIds.has(memoryId)) continue;
|
|
10512
10611
|
const paths = filePathsById.get(memoryId) ?? [];
|
|
10513
10612
|
paths.push(filePath);
|
|
@@ -10519,7 +10618,7 @@ ${current.content}
|
|
|
10519
10618
|
const preferredMatches = [];
|
|
10520
10619
|
for (const preferredPath of preferred) {
|
|
10521
10620
|
const directCandidates = new Set(qmdResultPathCandidates(this.baseDir, preferredPath));
|
|
10522
|
-
const directMatch = existingPaths.find((filePath) => directCandidates.has(
|
|
10621
|
+
const directMatch = existingPaths.find((filePath) => directCandidates.has(path15.resolve(filePath)));
|
|
10523
10622
|
if (directMatch) {
|
|
10524
10623
|
preferredMatches.push(directMatch);
|
|
10525
10624
|
continue;
|
|
@@ -10531,7 +10630,7 @@ ${current.content}
|
|
|
10531
10630
|
candidates.add(candidate);
|
|
10532
10631
|
}
|
|
10533
10632
|
}
|
|
10534
|
-
const match = existingPaths.find((filePath) => candidates.has(
|
|
10633
|
+
const match = existingPaths.find((filePath) => candidates.has(path15.resolve(filePath)));
|
|
10535
10634
|
if (match) preferredMatches.push(match);
|
|
10536
10635
|
}
|
|
10537
10636
|
if (preferredMatches.length > 0) {
|
|
@@ -10853,11 +10952,11 @@ ${current.content}
|
|
|
10853
10952
|
}
|
|
10854
10953
|
}
|
|
10855
10954
|
get summariesDir() {
|
|
10856
|
-
return
|
|
10955
|
+
return path15.join(this.baseDir, "summaries");
|
|
10857
10956
|
}
|
|
10858
10957
|
async writeSummary(summary) {
|
|
10859
10958
|
await mkdir2(this.summariesDir, { recursive: true });
|
|
10860
|
-
const filePath =
|
|
10959
|
+
const filePath = path15.join(this.summariesDir, `${summary.id}.json`);
|
|
10861
10960
|
await this.writeStorageSecureFile(filePath, JSON.stringify(summary, null, 2));
|
|
10862
10961
|
log.debug(`wrote summary ${summary.id}`);
|
|
10863
10962
|
}
|
|
@@ -10867,7 +10966,7 @@ ${current.content}
|
|
|
10867
10966
|
const summaries = [];
|
|
10868
10967
|
for (const file of files) {
|
|
10869
10968
|
if (isMacOsReplicationJunkBasename(file) || !file.endsWith(".json")) continue;
|
|
10870
|
-
const filePath =
|
|
10969
|
+
const filePath = path15.join(this.summariesDir, file);
|
|
10871
10970
|
const raw = await this.readStorageSecureFile(filePath);
|
|
10872
10971
|
summaries.push(JSON.parse(raw));
|
|
10873
10972
|
}
|
|
@@ -10937,13 +11036,13 @@ ${current.content}
|
|
|
10937
11036
|
return archived;
|
|
10938
11037
|
}
|
|
10939
11038
|
async saveTopics(topics) {
|
|
10940
|
-
const metaPath =
|
|
11039
|
+
const metaPath = path15.join(this.stateDir, "topics.json");
|
|
10941
11040
|
await mkdir2(this.stateDir, { recursive: true });
|
|
10942
11041
|
await this.writeStorageSecureFile(metaPath, JSON.stringify({ topics, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
10943
11042
|
log.debug(`saved ${topics.length} topic scores`);
|
|
10944
11043
|
}
|
|
10945
11044
|
async loadTopics() {
|
|
10946
|
-
const metaPath =
|
|
11045
|
+
const metaPath = path15.join(this.stateDir, "topics.json");
|
|
10947
11046
|
try {
|
|
10948
11047
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
10949
11048
|
return JSON.parse(raw);
|
|
@@ -11063,4 +11162,4 @@ export {
|
|
|
11063
11162
|
isValidBufferSurpriseEvent,
|
|
11064
11163
|
StorageManager3 as StorageManager
|
|
11065
11164
|
};
|
|
11066
|
-
//# sourceMappingURL=chunk-
|
|
11165
|
+
//# sourceMappingURL=chunk-GQIYL7OD.js.map
|