@remnic/core 9.54.4 → 9.54.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +24 -23
- package/dist/access-admin-ops-surface.js +55 -50
- package/dist/access-authorization-probe.d.ts +25 -22
- package/dist/access-authorization-probe.js +58 -51
- package/dist/access-boundary.d.ts +26 -23
- package/dist/access-boundary.js +59 -52
- package/dist/access-cli.js +115 -107
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +19 -18
- package/dist/access-extraction-force-flush.js +55 -50
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +22 -21
- package/dist/access-http-lifecycle-flush.d.ts +22 -21
- package/dist/access-http-offline-stream.d.ts +19 -18
- package/dist/access-http-query.js +55 -50
- package/dist/access-http.d.ts +55 -36
- package/dist/access-http.js +76 -65
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +55 -50
- package/dist/access-lcm-surface.d.ts +21 -20
- package/dist/access-lcm-surface.js +55 -50
- package/dist/access-mcp.d.ts +22 -21
- package/dist/access-mcp.js +63 -57
- package/dist/access-memory-search-fanout.d.ts +22 -2
- package/dist/access-memory-search-fanout.js +1 -1
- package/dist/{access-namespace-preflight-C7n4tgWC.d.ts → access-namespace-preflight-CCNn_6NE.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +55 -50
- package/dist/access-observe-write-surface.d.ts +22 -21
- package/dist/access-observe-write-surface.js +55 -50
- package/dist/access-offline-manifest.d.ts +10 -9
- package/dist/access-offline-manifest.js +12 -10
- package/dist/access-operations-batch.js +57 -52
- package/dist/access-operations.d.ts +23 -22
- package/dist/access-operations.js +61 -55
- package/dist/access-recall-concurrency.d.ts +21 -20
- package/dist/access-recall-concurrency.js +55 -50
- package/dist/access-recall-response.d.ts +19 -18
- package/dist/access-recall-response.js +55 -50
- package/dist/access-recall-surface.d.ts +19 -18
- package/dist/access-recall-surface.js +55 -50
- package/dist/access-schema.d.ts +2 -2
- package/dist/access-schema.js +5 -4
- package/dist/{access-service-CXvbxLK-.d.ts → access-service-DkSdXK4S.d.ts} +1314 -83
- package/dist/access-service-helpers.d.ts +22 -21
- package/dist/access-service.d.ts +31 -30
- package/dist/access-service.js +55 -50
- package/dist/access-surface-catalog.d.ts +22 -21
- package/dist/access-surface-catalog.js +209 -2
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +14 -1
- package/dist/active-memory-bridge.js +6 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +4 -2
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/admin-console/public/what-helps-me/app.js +1594 -0
- package/dist/admin-console/public/what-helps-me/index.html +339 -0
- package/dist/admin-console/public/what-helps-me/model.js +685 -0
- package/dist/admin-console/public/what-helps-me/what-helps-me.css +1296 -0
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-TDHLZPVP.js → auto-sync-NR3GPCOA.js} +4 -4
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +33 -12
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/buffer.js +3 -3
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-BOOxl-I2.d.ts → catalog-DGFf8mD9.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +34 -13
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-ZYLC7NFO.js → chunk-26ZXBTYN.js} +4 -4
- package/dist/chunk-26ZXBTYN.js.map +1 -0
- package/dist/{chunk-LLJMAULE.js → chunk-2FKEIPIT.js} +5 -5
- package/dist/{chunk-3CSX3ETE.js → chunk-2LWQSV6A.js} +23 -11
- package/dist/chunk-2LWQSV6A.js.map +1 -0
- package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
- package/dist/chunk-37DZZFFM.js +502 -0
- package/dist/chunk-37DZZFFM.js.map +1 -0
- package/dist/chunk-3HSRWJTC.js +9 -0
- package/dist/chunk-3HSRWJTC.js.map +1 -0
- package/dist/{chunk-XUAMCLY4.js → chunk-3TIZPSJC.js} +17 -13
- package/dist/chunk-3TIZPSJC.js.map +1 -0
- package/dist/{chunk-PDDTI7IC.js → chunk-43SEBY2M.js} +1 -1
- package/dist/{chunk-HWRD23DW.js → chunk-46SZBVDS.js} +3 -3
- package/dist/{chunk-6HPHEFXT.js → chunk-5FD7JMTX.js} +2 -2
- package/dist/{chunk-7BZOBA5J.js → chunk-5NB726GV.js} +70 -16
- package/dist/chunk-5NB726GV.js.map +1 -0
- package/dist/chunk-62OKGIJA.js +39 -0
- package/dist/chunk-62OKGIJA.js.map +1 -0
- package/dist/{chunk-IBKR2TFR.js → chunk-6CYHUWCO.js} +2 -2
- package/dist/{chunk-YN6ASZUG.js → chunk-6QPI2ITJ.js} +5 -5
- package/dist/{chunk-UU3G6GUP.js → chunk-76JJSXK7.js} +1 -1
- package/dist/chunk-76JJSXK7.js.map +1 -0
- package/dist/{chunk-PX2LSHYM.js → chunk-7BD6O7ZV.js} +189 -4
- package/dist/chunk-7BD6O7ZV.js.map +1 -0
- package/dist/chunk-7TBXNYLO.js +346 -0
- package/dist/chunk-7TBXNYLO.js.map +1 -0
- package/dist/{chunk-NH5IR2WM.js → chunk-BRR5EUTF.js} +6 -2
- package/dist/chunk-BRR5EUTF.js.map +1 -0
- package/dist/{chunk-NIS256NW.js → chunk-CIAI24TQ.js} +3 -3
- package/dist/{chunk-T2JHZWH6.js → chunk-D3LBIUWV.js} +11703 -7573
- package/dist/chunk-D3LBIUWV.js.map +1 -0
- package/dist/{chunk-7FGL6CGA.js → chunk-DVYRD4HY.js} +2 -2
- package/dist/{chunk-G7Z6EENO.js → chunk-EKTP7MNS.js} +4 -4
- package/dist/{chunk-S75M5ZRK.js → chunk-F2JRDPON.js} +16 -1
- package/dist/chunk-F2JRDPON.js.map +1 -0
- package/dist/{chunk-RZ4XGKOJ.js → chunk-FFRTNF3L.js} +8 -8
- package/dist/{chunk-VKXWK44Q.js → chunk-FONWBCVY.js} +3 -3
- package/dist/{chunk-DZD576ZU.js → chunk-FPLM2TKD.js} +2 -2
- package/dist/{chunk-ZPJ4QSGP.js → chunk-FTPONF6B.js} +2 -2
- package/dist/{chunk-LJS7KUPV.js → chunk-FWX7W5PM.js} +2 -2
- package/dist/{chunk-UTRO5UJU.js → chunk-G6DFSS6A.js} +5 -1
- package/dist/chunk-G6DFSS6A.js.map +1 -0
- package/dist/{chunk-6LAPLZOS.js → chunk-GJ776BC2.js} +8 -3
- package/dist/chunk-GJ776BC2.js.map +1 -0
- package/dist/{chunk-G4T7L557.js → chunk-GN3WRFJY.js} +6 -6
- package/dist/{chunk-QT2FRYI4.js → chunk-H7NAZ3UB.js} +2 -2
- package/dist/{chunk-APPFNGX6.js → chunk-HBUFQRIM.js} +2 -2
- package/dist/{chunk-UU7TRFNE.js → chunk-HGJ6NJ4E.js} +2 -2
- package/dist/{chunk-WB7JSQCP.js → chunk-HIEWDJ2O.js} +5 -2
- package/dist/{chunk-WB7JSQCP.js.map → chunk-HIEWDJ2O.js.map} +1 -1
- package/dist/{chunk-UES4BHA2.js → chunk-I3MSGFGD.js} +17 -6
- package/dist/chunk-I3MSGFGD.js.map +1 -0
- package/dist/{chunk-C4ZNGVK3.js → chunk-IKP5OYQQ.js} +2 -2
- package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
- package/dist/{chunk-RDJRFDJY.js → chunk-IQ4NVWEF.js} +2 -2
- package/dist/{chunk-CGVHPCP2.js → chunk-JYG4OLWH.js} +2 -2
- package/dist/{chunk-WOPA3SGI.js → chunk-K26NWEOC.js} +8 -8
- package/dist/{chunk-K4QS7LXU.js → chunk-K2UGPTYY.js} +485 -44
- package/dist/chunk-K2UGPTYY.js.map +1 -0
- package/dist/{chunk-L6CQ7WIW.js → chunk-KFBOPMF6.js} +11 -11
- package/dist/chunk-KFBOPMF6.js.map +1 -0
- package/dist/{chunk-G7A5HLUS.js → chunk-KJH6W2I7.js} +2 -2
- package/dist/{chunk-IXEBUYO4.js → chunk-KM55SMLG.js} +11 -2
- package/dist/{chunk-IXEBUYO4.js.map → chunk-KM55SMLG.js.map} +1 -1
- package/dist/{chunk-HOIRB77A.js → chunk-L6Z5OAS4.js} +2 -2
- package/dist/chunk-LC2BDILZ.js +57 -0
- package/dist/chunk-LC2BDILZ.js.map +1 -0
- package/dist/{chunk-227UFSEQ.js → chunk-LEPOP46W.js} +4 -4
- package/dist/{chunk-6R4G7N4S.js → chunk-M4YHAODQ.js} +388 -748
- package/dist/chunk-M4YHAODQ.js.map +1 -0
- package/dist/{chunk-3JLPGJ43.js → chunk-MIH3CJPN.js} +5 -5
- package/dist/{chunk-QHFV6VNU.js → chunk-MK5VEWCR.js} +2 -2
- package/dist/chunk-NISZQW72.js +140 -0
- package/dist/chunk-NISZQW72.js.map +1 -0
- package/dist/{chunk-GUKBW4HL.js → chunk-NQMSEB5D.js} +6 -6
- package/dist/{chunk-G2LUMAUF.js → chunk-OCIP6YMD.js} +12 -5
- package/dist/chunk-OCIP6YMD.js.map +1 -0
- package/dist/{chunk-47P3RYZP.js → chunk-PG4QBPVG.js} +21 -11
- package/dist/chunk-PG4QBPVG.js.map +1 -0
- package/dist/{chunk-WRJVB3C2.js → chunk-PO7NXBG2.js} +2 -2
- package/dist/{chunk-QWGE2PUH.js → chunk-PT54WISF.js} +190 -56
- package/dist/chunk-PT54WISF.js.map +1 -0
- package/dist/{chunk-AZM4CCAC.js → chunk-QZLDRQ4I.js} +8 -8
- package/dist/{chunk-THPPCISA.js → chunk-RBII7637.js} +5 -5
- package/dist/{chunk-JDZPNCMA.js → chunk-RUNORG2P.js} +6 -3
- package/dist/chunk-RUNORG2P.js.map +1 -0
- package/dist/{chunk-JV5YUBIZ.js → chunk-RZQ6W2W4.js} +50 -44
- package/dist/chunk-RZQ6W2W4.js.map +1 -0
- package/dist/{chunk-RUMNY5DT.js → chunk-SMNYAMJD.js} +6 -2
- package/dist/chunk-SMNYAMJD.js.map +1 -0
- package/dist/{chunk-MKQBXQKU.js → chunk-TB6CBZ5V.js} +22 -15
- package/dist/chunk-TB6CBZ5V.js.map +1 -0
- package/dist/{chunk-VMMQDEN5.js → chunk-TO7ZTWJW.js} +2 -2
- package/dist/{chunk-K2TDK7GG.js → chunk-TWTUGCTY.js} +2 -2
- package/dist/{chunk-HLYR2TQL.js → chunk-UCTS3DDH.js} +2 -2
- package/dist/{chunk-JYIJNNN3.js → chunk-UG6VXIOK.js} +2 -2
- package/dist/{chunk-WM65LU67.js → chunk-UKYS3NU5.js} +2 -2
- package/dist/{chunk-WDBX6VER.js → chunk-UPLZNJKN.js} +5 -5
- package/dist/{chunk-C23BYTJV.js → chunk-UW5NPZJ2.js} +40 -12
- package/dist/chunk-UW5NPZJ2.js.map +1 -0
- package/dist/{chunk-2GFK22OZ.js → chunk-V6ERBR7U.js} +2 -2
- package/dist/{chunk-CYF6WVE7.js → chunk-W5ZKPI34.js} +139 -158
- package/dist/chunk-W5ZKPI34.js.map +1 -0
- package/dist/chunk-XX4HPFFM.js +370 -0
- package/dist/chunk-XX4HPFFM.js.map +1 -0
- package/dist/{chunk-ZMYDYNI4.js → chunk-XZHE2DEN.js} +4 -4
- package/dist/chunk-YXQEKCZM.js +223 -0
- package/dist/chunk-YXQEKCZM.js.map +1 -0
- package/dist/{chunk-GYPQL6XN.js → chunk-Z4N7SVVF.js} +35 -47
- package/dist/chunk-Z4N7SVVF.js.map +1 -0
- package/dist/{chunk-MAXVH44E.js → chunk-Z54EM5YZ.js} +7 -7
- package/dist/{chunk-YGLY6QFV.js → chunk-ZRZVLB7O.js} +2 -2
- package/dist/{chunk-4IIFL7GC.js → chunk-ZUKIUXHQ.js} +10 -10
- package/dist/{cli-DVUFIa5E.d.ts → cli-Bze8S0Qs.d.ts} +5 -5
- package/dist/cli.d.ts +22 -21
- package/dist/cli.js +90 -80
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +33 -12
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +4 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +33 -12
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +32 -12
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +3 -1
- package/dist/contradiction-scan-JDTBXRGW.js +20 -0
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +35 -14
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +25 -24
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-XzF76C9n.d.ts → dependency-propagation-delivery-CzEfB31P.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +33 -12
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/explicit-capture.js +7 -4
- package/dist/external-wiki-access.d.ts +22 -21
- package/dist/external-wiki-access.js +56 -51
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +22 -21
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-faithfulness.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-judge.js +2 -2
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +35 -19
- package/dist/fallback-llm.d.ts +14 -1
- package/dist/fallback-llm.js +1 -1
- package/dist/{first-start-migration-626C5554.js → first-start-migration-CRZCZAJN.js} +11 -3
- package/dist/first-start-migration-CRZCZAJN.js.map +1 -0
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/index.d.ts +314 -308
- package/dist/index.js +304 -133
- package/dist/inline-script.d.ts +3 -0
- package/dist/inline-script.js +8 -0
- package/dist/inline-script.js.map +1 -0
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +6 -6
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +2 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +33 -12
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +33 -12
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +34 -13
- package/dist/{maintenance-BJzNIKBE.d.ts → maintenance-C8aRWfhq.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +22 -21
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-mutations.js +2 -2
- package/dist/memory-projection-store.d.ts +6 -2
- package/dist/memory-projection-store.js +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +24 -23
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +8 -8
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +33 -12
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-file-io.d.ts +20 -0
- package/dist/offline-sync-file-io.js +18 -0
- package/dist/offline-sync-file-io.js.map +1 -0
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/offline-sync-impression-drain.js +5 -5
- package/dist/offline-sync.d.ts +8 -6
- package/dist/offline-sync.js +2 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +26 -25
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +39 -36
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +38 -18
- package/dist/{orchestrator-BiXgBJBQ.d.ts → orchestrator-D85CzDDY.d.ts} +11 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +117 -109
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-sz_dcuLg.d.ts → pipeline-DPcUifCO.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/public-http-D-SyWNj6.d.ts +25 -0
- package/dist/{purge-533FZLS4.js → purge-GB7PZHT2.js} +2 -2
- package/dist/{qmd-eAWObK4M.d.ts → qmd-dFCHp1r0.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/recall-concurrency-config.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-planner-llm.js +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +2 -1
- package/dist/reconcile/manifest.d.ts +2 -1
- package/dist/reconcile/manifest.js +6 -5
- package/dist/reconcile/plan.d.ts +2 -1
- package/dist/reconcile/plan.js +3 -2
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +5 -3
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/schemas.d.ts +38 -38
- package/dist/{scope-profiles-BBQsXuyj.d.ts → scope-profiles-DICK7GtN.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +6 -6
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +12 -12
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-HD8RkzVA.d.ts → semantic-consolidation-BP7NAX0N.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +34 -13
- package/dist/semantic-rule-promotion.js +33 -12
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +33 -12
- package/dist/{service-DIrtHHEg.d.ts → service-DT-pJyda.d.ts} +660 -660
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +31 -15
- package/dist/{storage-DqCzXi56.d.ts → storage-qOnaJ1Lw.d.ts} +49 -13
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +33 -12
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +5 -5
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +518 -0
- package/dist/support-passport/index.js +357 -0
- package/dist/support-passport/index.js.map +1 -0
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +2 -2
- package/dist/tier-routing.js +7 -1
- package/dist/{tier-stats-2JCZYEF7.js → tier-stats-EXYSKSVN.js} +8 -2
- package/dist/{tier-stats-2JCZYEF7.js.map → tier-stats-EXYSKSVN.js.map} +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +1 -1
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/types.d.ts +36 -36
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-d_j4vC6N.d.ts → types-ed-SvS2t.d.ts} +8 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +2 -2
- package/dist/verified-recall.js +33 -12
- package/dist/write-envelope.d.ts +1 -1
- package/dist/write-rate-limiter.d.ts +11 -5
- package/dist/write-rate-limiter.js +1 -1
- package/package.json +12 -2
- package/scripts/build-with-heap.mjs +11 -1
- package/src/access-authorization-probe.ts +20 -2
- package/src/access-boundary.ts +32 -0
- package/src/access-http.test.ts +1971 -643
- package/src/access-http.ts +81 -74
- package/src/access-mcp.ts +3 -1
- package/src/access-memory-search-fanout.ts +24 -1
- package/src/access-offline-manifest.ts +5 -0
- package/src/access-operations.ts +2 -0
- package/src/access-service-namespace.test.ts +14 -0
- package/src/access-service-observe-scope.test.ts +2 -0
- package/src/access-service-offline-file-content.test.ts +211 -0
- package/src/access-service.ts +628 -884
- package/src/access-surface-catalog.test.ts +40 -10
- package/src/access-surface-catalog.ts +15 -0
- package/src/active-memory-bridge.test.ts +151 -0
- package/src/active-memory-bridge.ts +95 -21
- package/src/briefing.test.ts +38 -0
- package/src/briefing.ts +3 -3
- package/src/cli.ts +6 -1
- package/src/config.ts +18 -9
- package/src/connectors/codex-materialize-runner.ts +2 -0
- package/src/contradiction/contradiction-scan.ts +2 -0
- package/src/contradiction/contradiction.test.ts +42 -0
- package/src/correction/correction-access-wiring.ts +8 -2
- package/src/correction/correction-storage-integration.test.ts +7 -0
- package/src/explicit-capture.test.ts +24 -0
- package/src/explicit-capture.ts +2 -0
- package/src/fallback-llm.test.ts +54 -0
- package/src/fallback-llm.ts +54 -9
- package/src/index.ts +3 -0
- package/src/inline-script.ts +6 -0
- package/src/local-llm-headers-timeout.test.ts +42 -0
- package/src/local-llm.ts +8 -8
- package/src/maintenance/first-start-migration.ts +2 -1
- package/src/maintenance/memory-governance.test.ts +25 -0
- package/src/maintenance/memory-governance.ts +4 -1
- package/src/maintenance/pattern-reinforcement.test.ts +20 -0
- package/src/maintenance/pattern-reinforcement.ts +2 -1
- package/src/maintenance/rebuild-memory-projection.ts +8 -8
- package/src/mcp-read-only-tools.ts +3 -0
- package/src/memory-projection-store.ts +25 -27
- package/src/offline-sync-file-io.ts +68 -0
- package/src/offline-sync.ts +43 -57
- package/src/orchestration/consolidation-run.ts +5 -4
- package/src/orchestration/contradiction-linking-coordinator.ts +7 -0
- package/src/orchestration/contradiction-localization.integration.test.ts +115 -0
- package/src/orchestration/lifecycle-policy-coordinator.ts +2 -1
- package/src/orchestration/qmd-result-resolver.test.ts +215 -14
- package/src/orchestration/qmd-result-resolver.ts +142 -82
- package/src/orchestration/recall-search-pipeline.test.ts +41 -0
- package/src/orchestration/recall-search-pipeline.ts +12 -0
- package/src/orchestration/semantic-consolidation-coordinator.ts +2 -1
- package/src/orchestration/tier-migration-coordinator.ts +23 -56
- package/src/orchestration/workspace-ops.test.ts +37 -0
- package/src/orchestration/workspace-ops.ts +5 -29
- package/src/orchestrator.ts +7 -8
- package/src/relay/mission-access.test.ts +11 -11
- package/src/relay/mission-ui.test.ts +3 -1
- package/src/storage/supersession-audit.ts +7 -1
- package/src/storage/supersession-side-effects.ts +17 -5
- package/src/storage/tombstone-blocked-capture-sync.ts +31 -0
- package/src/storage-contract/failure-semantics.test.ts +102 -0
- package/src/storage.ts +18 -19
- package/src/support-passport/access-http-base.ts +143 -0
- package/src/support-passport/access-http.ts +172 -0
- package/src/support-passport/access-operations.ts +272 -0
- package/src/support-passport/access-service-base.test.ts +193 -0
- package/src/support-passport/access-service-base.ts +176 -0
- package/src/support-passport/access-surface.test.ts +283 -0
- package/src/support-passport/access-surface.ts +286 -0
- package/src/support-passport/card-projection.test.ts +137 -0
- package/src/support-passport/card-projection.ts +348 -0
- package/src/support-passport/card-replacement.ts +126 -0
- package/src/support-passport/card-service-commit-forwarding.test.ts +160 -0
- package/src/support-passport/card-service.test.ts +2964 -0
- package/src/support-passport/card-service.ts +1184 -0
- package/src/support-passport/card-state.ts +158 -0
- package/src/support-passport/config-model-routing.test.ts +37 -0
- package/src/support-passport/config.test.ts +34 -0
- package/src/support-passport/config.ts +41 -0
- package/src/support-passport/contracts.test.ts +156 -0
- package/src/support-passport/contracts.ts +149 -0
- package/src/support-passport/errors.ts +30 -0
- package/src/support-passport/generated-batch.test.ts +185 -0
- package/src/support-passport/generated-batch.ts +338 -0
- package/src/support-passport/grant-contracts.ts +183 -0
- package/src/support-passport/grant-generated-batch-scope.test.ts +201 -0
- package/src/support-passport/grant-service-cache.test.ts +148 -0
- package/src/support-passport/grant-service-cancellation.test.ts +83 -0
- package/src/support-passport/grant-service-marker-cache.test.ts +62 -0
- package/src/support-passport/grant-service.test.ts +3496 -0
- package/src/support-passport/grant-service.ts +513 -0
- package/src/support-passport/grant-store-commit-hook.test.ts +123 -0
- package/src/support-passport/grant-store-order.test.ts +60 -0
- package/src/support-passport/grant-store-path-safety.test.ts +30 -0
- package/src/support-passport/grant-store-recovery.test.ts +448 -0
- package/src/support-passport/grant-store.ts +906 -0
- package/src/support-passport/index.ts +17 -0
- package/src/support-passport/mcp-tools.test.ts +222 -0
- package/src/support-passport/mcp-tools.ts +187 -0
- package/src/support-passport/model-adapter.test.ts +840 -0
- package/src/support-passport/model-adapter.ts +602 -0
- package/src/support-passport/model-audit-pinned-write.test.ts +59 -0
- package/src/support-passport/model-audit.ts +152 -0
- package/src/support-passport/model-bridge.test.ts +456 -0
- package/src/support-passport/model-bridge.ts +439 -0
- package/src/support-passport/model-contracts.ts +124 -0
- package/src/support-passport/model-service.test.ts +1731 -0
- package/src/support-passport/model-service.ts +399 -0
- package/src/support-passport/offline-sync-guard.ts +230 -0
- package/src/support-passport/owner-http.test.ts +671 -0
- package/src/support-passport/owner-lock.ts +70 -0
- package/src/support-passport/private-file.test.ts +99 -0
- package/src/support-passport/private-file.ts +498 -0
- package/src/support-passport/public-http.test.ts +476 -0
- package/src/support-passport/public-http.ts +601 -0
- package/src/support-passport/ui.test.ts +181 -0
- package/src/tier-routing.ts +28 -17
- package/src/training-export/converter.test.ts +24 -0
- package/src/training-export/converter.ts +2 -0
- package/src/types.ts +8 -1
- package/src/wearables/service.test.ts +13 -0
- package/src/wearables/service.ts +2 -0
- package/src/write-rate-limiter.test.ts +30 -6
- package/src/write-rate-limiter.ts +29 -18
- package/dist/chunk-3CSX3ETE.js.map +0 -1
- package/dist/chunk-47P3RYZP.js.map +0 -1
- package/dist/chunk-6LAPLZOS.js.map +0 -1
- package/dist/chunk-6R4G7N4S.js.map +0 -1
- package/dist/chunk-7BZOBA5J.js.map +0 -1
- package/dist/chunk-C23BYTJV.js.map +0 -1
- package/dist/chunk-CYF6WVE7.js.map +0 -1
- package/dist/chunk-G2LUMAUF.js.map +0 -1
- package/dist/chunk-GYPQL6XN.js.map +0 -1
- package/dist/chunk-JDZPNCMA.js.map +0 -1
- package/dist/chunk-JV5YUBIZ.js.map +0 -1
- package/dist/chunk-K4QS7LXU.js.map +0 -1
- package/dist/chunk-L6CQ7WIW.js.map +0 -1
- package/dist/chunk-MKQBXQKU.js.map +0 -1
- package/dist/chunk-NH5IR2WM.js.map +0 -1
- package/dist/chunk-PX2LSHYM.js.map +0 -1
- package/dist/chunk-QWGE2PUH.js.map +0 -1
- package/dist/chunk-RUMNY5DT.js.map +0 -1
- package/dist/chunk-S75M5ZRK.js.map +0 -1
- package/dist/chunk-T2JHZWH6.js.map +0 -1
- package/dist/chunk-UES4BHA2.js.map +0 -1
- package/dist/chunk-UTRO5UJU.js.map +0 -1
- package/dist/chunk-UU3G6GUP.js.map +0 -1
- package/dist/chunk-XUAMCLY4.js.map +0 -1
- package/dist/chunk-ZYLC7NFO.js.map +0 -1
- package/dist/contradiction-scan-HYLIRMJ2.js +0 -14
- package/dist/first-start-migration-626C5554.js.map +0 -1
- /package/dist/{auto-sync-TDHLZPVP.js.map → auto-sync-NR3GPCOA.js.map} +0 -0
- /package/dist/{chunk-LLJMAULE.js.map → chunk-2FKEIPIT.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-PDDTI7IC.js.map → chunk-43SEBY2M.js.map} +0 -0
- /package/dist/{chunk-HWRD23DW.js.map → chunk-46SZBVDS.js.map} +0 -0
- /package/dist/{chunk-6HPHEFXT.js.map → chunk-5FD7JMTX.js.map} +0 -0
- /package/dist/{chunk-IBKR2TFR.js.map → chunk-6CYHUWCO.js.map} +0 -0
- /package/dist/{chunk-YN6ASZUG.js.map → chunk-6QPI2ITJ.js.map} +0 -0
- /package/dist/{chunk-NIS256NW.js.map → chunk-CIAI24TQ.js.map} +0 -0
- /package/dist/{chunk-7FGL6CGA.js.map → chunk-DVYRD4HY.js.map} +0 -0
- /package/dist/{chunk-G7Z6EENO.js.map → chunk-EKTP7MNS.js.map} +0 -0
- /package/dist/{chunk-RZ4XGKOJ.js.map → chunk-FFRTNF3L.js.map} +0 -0
- /package/dist/{chunk-VKXWK44Q.js.map → chunk-FONWBCVY.js.map} +0 -0
- /package/dist/{chunk-DZD576ZU.js.map → chunk-FPLM2TKD.js.map} +0 -0
- /package/dist/{chunk-ZPJ4QSGP.js.map → chunk-FTPONF6B.js.map} +0 -0
- /package/dist/{chunk-LJS7KUPV.js.map → chunk-FWX7W5PM.js.map} +0 -0
- /package/dist/{chunk-G4T7L557.js.map → chunk-GN3WRFJY.js.map} +0 -0
- /package/dist/{chunk-QT2FRYI4.js.map → chunk-H7NAZ3UB.js.map} +0 -0
- /package/dist/{chunk-APPFNGX6.js.map → chunk-HBUFQRIM.js.map} +0 -0
- /package/dist/{chunk-UU7TRFNE.js.map → chunk-HGJ6NJ4E.js.map} +0 -0
- /package/dist/{chunk-C4ZNGVK3.js.map → chunk-IKP5OYQQ.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
- /package/dist/{chunk-RDJRFDJY.js.map → chunk-IQ4NVWEF.js.map} +0 -0
- /package/dist/{chunk-CGVHPCP2.js.map → chunk-JYG4OLWH.js.map} +0 -0
- /package/dist/{chunk-WOPA3SGI.js.map → chunk-K26NWEOC.js.map} +0 -0
- /package/dist/{chunk-G7A5HLUS.js.map → chunk-KJH6W2I7.js.map} +0 -0
- /package/dist/{chunk-HOIRB77A.js.map → chunk-L6Z5OAS4.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-LEPOP46W.js.map} +0 -0
- /package/dist/{chunk-3JLPGJ43.js.map → chunk-MIH3CJPN.js.map} +0 -0
- /package/dist/{chunk-QHFV6VNU.js.map → chunk-MK5VEWCR.js.map} +0 -0
- /package/dist/{chunk-GUKBW4HL.js.map → chunk-NQMSEB5D.js.map} +0 -0
- /package/dist/{chunk-WRJVB3C2.js.map → chunk-PO7NXBG2.js.map} +0 -0
- /package/dist/{chunk-AZM4CCAC.js.map → chunk-QZLDRQ4I.js.map} +0 -0
- /package/dist/{chunk-THPPCISA.js.map → chunk-RBII7637.js.map} +0 -0
- /package/dist/{chunk-VMMQDEN5.js.map → chunk-TO7ZTWJW.js.map} +0 -0
- /package/dist/{chunk-K2TDK7GG.js.map → chunk-TWTUGCTY.js.map} +0 -0
- /package/dist/{chunk-HLYR2TQL.js.map → chunk-UCTS3DDH.js.map} +0 -0
- /package/dist/{chunk-JYIJNNN3.js.map → chunk-UG6VXIOK.js.map} +0 -0
- /package/dist/{chunk-WM65LU67.js.map → chunk-UKYS3NU5.js.map} +0 -0
- /package/dist/{chunk-WDBX6VER.js.map → chunk-UPLZNJKN.js.map} +0 -0
- /package/dist/{chunk-2GFK22OZ.js.map → chunk-V6ERBR7U.js.map} +0 -0
- /package/dist/{chunk-ZMYDYNI4.js.map → chunk-XZHE2DEN.js.map} +0 -0
- /package/dist/{chunk-MAXVH44E.js.map → chunk-Z54EM5YZ.js.map} +0 -0
- /package/dist/{chunk-YGLY6QFV.js.map → chunk-ZRZVLB7O.js.map} +0 -0
- /package/dist/{chunk-4IIFL7GC.js.map → chunk-ZUKIUXHQ.js.map} +0 -0
- /package/dist/{contradiction-scan-HYLIRMJ2.js.map → contradiction-scan-JDTBXRGW.js.map} +0 -0
- /package/dist/{purge-533FZLS4.js.map → purge-GB7PZHT2.js.map} +0 -0
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TombstoneStore,
|
|
3
|
+
applyTombstoneResurrectionGate,
|
|
4
|
+
buildRetiredFactTombstoneInputs,
|
|
5
|
+
collectRetiredMemoriesForRebuild
|
|
6
|
+
} from "./chunk-MLPTFODV.js";
|
|
1
7
|
import {
|
|
2
8
|
WEARABLES_DIR_NAME,
|
|
3
9
|
escapeSegmentText,
|
|
@@ -10,18 +16,15 @@ import {
|
|
|
10
16
|
unescapeSpeakerLabel
|
|
11
17
|
} from "./chunk-UHVXE24Y.js";
|
|
12
18
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
buildRetiredFactTombstoneInputs,
|
|
16
|
-
collectRetiredMemoriesForRebuild
|
|
17
|
-
} from "./chunk-MLPTFODV.js";
|
|
19
|
+
normalizeQmdResultPath
|
|
20
|
+
} from "./chunk-TO7ZTWJW.js";
|
|
18
21
|
import {
|
|
19
22
|
withholdToolScopedFromSharedNamespace
|
|
20
23
|
} from "./chunk-S2V7RUCL.js";
|
|
21
24
|
import {
|
|
22
25
|
SPECULATIVE_TTL_DAYS,
|
|
23
26
|
confidenceTier
|
|
24
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-76JJSXK7.js";
|
|
25
28
|
import {
|
|
26
29
|
normalizeProjectionPreview,
|
|
27
30
|
normalizeProjectionTags
|
|
@@ -29,7 +32,7 @@ import {
|
|
|
29
32
|
import {
|
|
30
33
|
rewriteProjectedEntityReferences,
|
|
31
34
|
rewriteProjectedMemoryEntityReference
|
|
32
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-PO7NXBG2.js";
|
|
33
36
|
import {
|
|
34
37
|
createMemorySnapshot
|
|
35
38
|
} from "./chunk-S2HLHAZ4.js";
|
|
@@ -48,15 +51,17 @@ import {
|
|
|
48
51
|
import {
|
|
49
52
|
parseFaithfulnessField,
|
|
50
53
|
serializeFaithfulnessFields
|
|
51
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-UG6VXIOK.js";
|
|
52
55
|
import {
|
|
56
|
+
DeletionRevisionStore,
|
|
53
57
|
TombstoneBlockedCaptureIndexHost,
|
|
54
58
|
buildCapturePathLockIdentity,
|
|
55
59
|
buildExplicitCaptureDedupKey,
|
|
60
|
+
invalidationCommitFingerprint,
|
|
56
61
|
isQueuedReviewMemory,
|
|
57
62
|
parseTombstoneBlockedOfflineSyncMemory,
|
|
58
63
|
tombstoneBlocked
|
|
59
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-K2UGPTYY.js";
|
|
60
65
|
import {
|
|
61
66
|
composeMemoryEnvelope,
|
|
62
67
|
isSealedMemoryEnvelope,
|
|
@@ -153,10 +158,7 @@ import {
|
|
|
153
158
|
readMemoryActionEventRowsFromLines,
|
|
154
159
|
readProjectionRebuiltAt,
|
|
155
160
|
serializeLifecycleAppendPayload
|
|
156
|
-
} from "./chunk-
|
|
157
|
-
import {
|
|
158
|
-
namespaceIdentityFromToken
|
|
159
|
-
} from "./chunk-EGGE52UU.js";
|
|
161
|
+
} from "./chunk-DVYRD4HY.js";
|
|
160
162
|
import {
|
|
161
163
|
assertMemoryFrontmatterId,
|
|
162
164
|
warnProjectionFallback
|
|
@@ -182,18 +184,24 @@ import {
|
|
|
182
184
|
readProjectedMemoryState,
|
|
183
185
|
readProjectedMemoryTimeline,
|
|
184
186
|
updateProjectedMemoryPath
|
|
185
|
-
} from "./chunk-
|
|
186
|
-
import {
|
|
187
|
-
assemblePersistedBody,
|
|
188
|
-
storedContentIdentityCandidates,
|
|
189
|
-
stripAttributesSuffix
|
|
190
|
-
} from "./chunk-JDSVLVCG.js";
|
|
187
|
+
} from "./chunk-2LWQSV6A.js";
|
|
191
188
|
import {
|
|
192
189
|
withHeldFileLock
|
|
193
190
|
} from "./chunk-FFAZ2XFU.js";
|
|
194
191
|
import {
|
|
195
192
|
computeLegacyContentHash
|
|
196
193
|
} from "./chunk-5FVVY2EB.js";
|
|
194
|
+
import {
|
|
195
|
+
isSupportPassportPrivateMemory
|
|
196
|
+
} from "./chunk-XX4HPFFM.js";
|
|
197
|
+
import {
|
|
198
|
+
namespaceIdentityFromToken
|
|
199
|
+
} from "./chunk-EGGE52UU.js";
|
|
200
|
+
import {
|
|
201
|
+
assemblePersistedBody,
|
|
202
|
+
storedContentIdentityCandidates,
|
|
203
|
+
stripAttributesSuffix
|
|
204
|
+
} from "./chunk-JDSVLVCG.js";
|
|
197
205
|
import {
|
|
198
206
|
sanitizeMemoryContent
|
|
199
207
|
} from "./chunk-5GKPFL3S.js";
|
|
@@ -224,6 +232,7 @@ import {
|
|
|
224
232
|
isErrnoCode
|
|
225
233
|
} from "./chunk-5UZXUTVO.js";
|
|
226
234
|
import {
|
|
235
|
+
ALL_CATEGORY_DIRS,
|
|
227
236
|
RECALL_FALLBACK_DIRS,
|
|
228
237
|
categoryDirName,
|
|
229
238
|
getCategoryDir
|
|
@@ -234,20 +243,20 @@ import {
|
|
|
234
243
|
|
|
235
244
|
// src/storage.ts
|
|
236
245
|
import {
|
|
237
|
-
lstat as
|
|
246
|
+
lstat as lstat3,
|
|
238
247
|
readdir as readdir6,
|
|
239
|
-
readFile as
|
|
248
|
+
readFile as readFile2,
|
|
240
249
|
realpath as realpath3,
|
|
241
250
|
stat as stat2,
|
|
242
251
|
writeFile as writeFile2,
|
|
243
|
-
mkdir
|
|
244
|
-
unlink as
|
|
252
|
+
mkdir,
|
|
253
|
+
unlink as unlink4,
|
|
245
254
|
appendFile,
|
|
246
|
-
open
|
|
255
|
+
open
|
|
247
256
|
} from "fs/promises";
|
|
248
257
|
import { appendFileSync, createReadStream, mkdirSync, statSync } from "fs";
|
|
249
|
-
import { createHash as
|
|
250
|
-
import
|
|
258
|
+
import { createHash as createHash6 } from "crypto";
|
|
259
|
+
import path10 from "path";
|
|
251
260
|
|
|
252
261
|
// src/storage/memory-read-store.ts
|
|
253
262
|
import { lstat, readdir, realpath, stat } from "fs/promises";
|
|
@@ -2080,425 +2089,9 @@ ${rows.join("\n")}
|
|
|
2080
2089
|
}
|
|
2081
2090
|
};
|
|
2082
2091
|
|
|
2083
|
-
// src/storage/deletion-revision-store.ts
|
|
2084
|
-
import { createHash, randomUUID } from "crypto";
|
|
2085
|
-
import { lstat as lstat2, mkdir, open, readFile, rename, unlink as unlink2 } from "fs/promises";
|
|
2086
|
-
import path3 from "path";
|
|
2087
|
-
var DELETION_REVISION_MAX_MTIME_MS = 864e13;
|
|
2088
|
-
var DELETION_REVISION_LOCK_STALE_MS = 6e4;
|
|
2089
|
-
var DELETION_REVISION_LOCK_MAX_WAIT_MS = 12e4;
|
|
2090
|
-
var INVALIDATION_COMMIT_MAX_TIMESTAMP_MS = 864e13;
|
|
2091
|
-
var INVALIDATION_PROOF_QUARANTINE_MAX_IDS = 1024;
|
|
2092
|
-
function canonicalizeInvalidationEvidence(value) {
|
|
2093
|
-
if (Array.isArray(value)) return value.map((item) => canonicalizeInvalidationEvidence(item));
|
|
2094
|
-
if (value && typeof value === "object") {
|
|
2095
|
-
const result = {};
|
|
2096
|
-
for (const key of Object.keys(value).sort()) {
|
|
2097
|
-
result[key] = canonicalizeInvalidationEvidence(value[key]);
|
|
2098
|
-
}
|
|
2099
|
-
return result;
|
|
2100
|
-
}
|
|
2101
|
-
return value;
|
|
2102
|
-
}
|
|
2103
|
-
function invalidationCommitFingerprint(memory) {
|
|
2104
|
-
const frontmatter = { ...memory.frontmatter };
|
|
2105
|
-
delete frontmatter.accessCount;
|
|
2106
|
-
delete frontmatter.lastAccessed;
|
|
2107
|
-
return createHash("sha256").update(
|
|
2108
|
-
JSON.stringify(
|
|
2109
|
-
canonicalizeInvalidationEvidence({
|
|
2110
|
-
content: memory.content,
|
|
2111
|
-
frontmatter
|
|
2112
|
-
})
|
|
2113
|
-
)
|
|
2114
|
-
).digest("hex");
|
|
2115
|
-
}
|
|
2116
|
-
function isValidInvalidationCommitTimestamp(value) {
|
|
2117
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= INVALIDATION_COMMIT_MAX_TIMESTAMP_MS;
|
|
2118
|
-
}
|
|
2119
|
-
function isValidInvalidationCommitFingerprint(value) {
|
|
2120
|
-
return typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
2121
|
-
}
|
|
2122
|
-
function isValidMemoryId(value) {
|
|
2123
|
-
return typeof value === "string" && value.length > 0 && !value.includes("\0");
|
|
2124
|
-
}
|
|
2125
|
-
function isValidDeletionRevisionPath(value) {
|
|
2126
|
-
return typeof value === "string" && value.length > 0 && !value.includes("\\") && !value.includes("\0") && !path3.posix.isAbsolute(value) && path3.posix.normalize(value) === value && value !== "." && value !== ".." && !value.startsWith("../");
|
|
2127
|
-
}
|
|
2128
|
-
function deletionRevisionPathIdentity(value) {
|
|
2129
|
-
return value.normalize("NFC").toUpperCase().toLowerCase();
|
|
2130
|
-
}
|
|
2131
|
-
var DeletionRevisionStore = class {
|
|
2132
|
-
options;
|
|
2133
|
-
invalidationProofQuarantine = /* @__PURE__ */ new Set();
|
|
2134
|
-
invalidationProofQuarantineFull = false;
|
|
2135
|
-
invalidationProofQuarantineFullAt = null;
|
|
2136
|
-
constructor(options) {
|
|
2137
|
-
this.options = options;
|
|
2138
|
-
}
|
|
2139
|
-
quarantineInvalidationProof(memoryId) {
|
|
2140
|
-
if (this.invalidationProofQuarantineFull) {
|
|
2141
|
-
const nextBoundary = Date.now() + 1;
|
|
2142
|
-
this.invalidationProofQuarantineFullAt = Math.max(
|
|
2143
|
-
this.invalidationProofQuarantineFullAt ?? 0,
|
|
2144
|
-
nextBoundary
|
|
2145
|
-
);
|
|
2146
|
-
return;
|
|
2147
|
-
}
|
|
2148
|
-
if (this.invalidationProofQuarantine.has(memoryId)) return;
|
|
2149
|
-
if (this.invalidationProofQuarantine.size >= INVALIDATION_PROOF_QUARANTINE_MAX_IDS) {
|
|
2150
|
-
this.invalidationProofQuarantineFull = true;
|
|
2151
|
-
this.invalidationProofQuarantineFullAt = Date.now() + 1;
|
|
2152
|
-
return;
|
|
2153
|
-
}
|
|
2154
|
-
this.invalidationProofQuarantine.add(memoryId);
|
|
2155
|
-
}
|
|
2156
|
-
async resolveConfiguredStoragePath(targetPath) {
|
|
2157
|
-
const baseDir = path3.resolve(this.options.baseDir);
|
|
2158
|
-
const relativePath = path3.relative(baseDir, path3.resolve(targetPath));
|
|
2159
|
-
return resolveSafeStoragePath(baseDir, relativePath);
|
|
2160
|
-
}
|
|
2161
|
-
async resolveManagedStoragePath(filePath, method) {
|
|
2162
|
-
const assertedPath = this.options.assertManagedStoragePath(filePath, method);
|
|
2163
|
-
const target = await this.resolveConfiguredStoragePath(assertedPath);
|
|
2164
|
-
const relativePath = path3.relative(path3.resolve(this.options.baseDir), target).split(path3.sep).join("/");
|
|
2165
|
-
return { target, relativePath };
|
|
2166
|
-
}
|
|
2167
|
-
parseDeletionRevisionMetadata(raw) {
|
|
2168
|
-
let parsed;
|
|
2169
|
-
try {
|
|
2170
|
-
parsed = JSON.parse(raw);
|
|
2171
|
-
} catch {
|
|
2172
|
-
throw new Error("Deletion revision metadata is invalid.");
|
|
2173
|
-
}
|
|
2174
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2175
|
-
throw new Error("Deletion revision metadata is invalid.");
|
|
2176
|
-
}
|
|
2177
|
-
const root = parsed;
|
|
2178
|
-
if (Object.keys(root).sort().join(",") !== "deletions,version" || root.version !== 1 || !Array.isArray(root.deletions)) {
|
|
2179
|
-
throw new Error("Deletion revision metadata is invalid.");
|
|
2180
|
-
}
|
|
2181
|
-
const revisions = /* @__PURE__ */ new Map();
|
|
2182
|
-
const pathByIdentity = /* @__PURE__ */ new Map();
|
|
2183
|
-
for (const rawEntry of root.deletions) {
|
|
2184
|
-
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) {
|
|
2185
|
-
throw new Error("Deletion revision metadata is invalid.");
|
|
2186
|
-
}
|
|
2187
|
-
const entry = rawEntry;
|
|
2188
|
-
if (Object.keys(entry).sort().join(",") !== "mtimeMs,path" || !isValidDeletionRevisionPath(entry.path) || typeof entry.mtimeMs !== "number" || !Number.isFinite(entry.mtimeMs) || entry.mtimeMs < 0 || entry.mtimeMs > DELETION_REVISION_MAX_MTIME_MS || revisions.has(entry.path)) {
|
|
2189
|
-
throw new Error("Deletion revision metadata is invalid.");
|
|
2190
|
-
}
|
|
2191
|
-
const identity = deletionRevisionPathIdentity(entry.path);
|
|
2192
|
-
if (pathByIdentity.has(identity)) {
|
|
2193
|
-
throw new Error("Deletion revision metadata is invalid.");
|
|
2194
|
-
}
|
|
2195
|
-
pathByIdentity.set(identity, entry.path);
|
|
2196
|
-
revisions.set(entry.path, entry.mtimeMs);
|
|
2197
|
-
}
|
|
2198
|
-
return new Map([...revisions.entries()].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0));
|
|
2199
|
-
}
|
|
2200
|
-
async readDeletionRevisionMetadata() {
|
|
2201
|
-
const metadataPath = await this.resolveConfiguredStoragePath(this.options.deletionRevisionMetadataPath);
|
|
2202
|
-
let raw;
|
|
2203
|
-
try {
|
|
2204
|
-
raw = await readFile(metadataPath, "utf8");
|
|
2205
|
-
} catch (error) {
|
|
2206
|
-
if (isErrnoCode(error, "ENOENT")) return /* @__PURE__ */ new Map();
|
|
2207
|
-
throw new Error("Deletion revision metadata is unavailable.");
|
|
2208
|
-
}
|
|
2209
|
-
return this.parseDeletionRevisionMetadata(raw);
|
|
2210
|
-
}
|
|
2211
|
-
async writeDeletionRevisionMetadata(revisions, lock) {
|
|
2212
|
-
const metadataPath = await this.resolveConfiguredStoragePath(this.options.deletionRevisionMetadataPath);
|
|
2213
|
-
const deletions = [...revisions.entries()].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([entryPath, mtimeMs]) => ({ path: entryPath, mtimeMs }));
|
|
2214
|
-
const metadata = { version: 1, deletions };
|
|
2215
|
-
const temporaryPath = await this.resolveConfiguredStoragePath(
|
|
2216
|
-
`${metadataPath}.${process.pid}.${randomUUID()}.tmp`
|
|
2217
|
-
);
|
|
2218
|
-
let handle = null;
|
|
2219
|
-
try {
|
|
2220
|
-
handle = await open(temporaryPath, "wx", 384);
|
|
2221
|
-
await handle.writeFile(`${JSON.stringify(metadata)}
|
|
2222
|
-
`, "utf8");
|
|
2223
|
-
await handle.sync();
|
|
2224
|
-
await handle.close();
|
|
2225
|
-
handle = null;
|
|
2226
|
-
if (!await lock.refresh()) {
|
|
2227
|
-
throw new Error("Deletion revision metadata lock was lost.");
|
|
2228
|
-
}
|
|
2229
|
-
const renameTarget = await this.resolveConfiguredStoragePath(this.options.deletionRevisionMetadataPath);
|
|
2230
|
-
await rename(temporaryPath, renameTarget);
|
|
2231
|
-
} finally {
|
|
2232
|
-
if (handle !== null) {
|
|
2233
|
-
await handle.close().catch((error) => {
|
|
2234
|
-
log.warn("failed to close deletion revision metadata temporary file", error);
|
|
2235
|
-
});
|
|
2236
|
-
}
|
|
2237
|
-
const cleanupPath = await this.resolveConfiguredStoragePath(temporaryPath).catch((error) => {
|
|
2238
|
-
log.warn("failed to resolve deletion revision metadata temporary file for cleanup", error);
|
|
2239
|
-
return null;
|
|
2240
|
-
});
|
|
2241
|
-
if (cleanupPath !== null) {
|
|
2242
|
-
await unlink2(cleanupPath).catch((error) => {
|
|
2243
|
-
if (!isErrnoCode(error, "ENOENT")) {
|
|
2244
|
-
log.warn("failed to clean up deletion revision metadata temporary file", error);
|
|
2245
|
-
}
|
|
2246
|
-
});
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
}
|
|
2250
|
-
async withDeletionRevisionLock(task) {
|
|
2251
|
-
const lockPath2 = await this.resolveConfiguredStoragePath(this.options.deletionRevisionLockPath);
|
|
2252
|
-
return withHeldFileLock(
|
|
2253
|
-
lockPath2,
|
|
2254
|
-
{
|
|
2255
|
-
staleMs: DELETION_REVISION_LOCK_STALE_MS,
|
|
2256
|
-
maxWaitMs: DELETION_REVISION_LOCK_MAX_WAIT_MS
|
|
2257
|
-
},
|
|
2258
|
-
async (acquired, lock) => {
|
|
2259
|
-
if (!acquired) throw new Error("Deletion revision metadata lock is unavailable.");
|
|
2260
|
-
return task(lock);
|
|
2261
|
-
}
|
|
2262
|
-
);
|
|
2263
|
-
}
|
|
2264
|
-
async readDeletionRevisions() {
|
|
2265
|
-
return this.withDeletionRevisionLock(async () => this.readDeletionRevisionMetadata());
|
|
2266
|
-
}
|
|
2267
|
-
parseInvalidationCommitMetadata(raw) {
|
|
2268
|
-
let parsed;
|
|
2269
|
-
try {
|
|
2270
|
-
parsed = JSON.parse(raw);
|
|
2271
|
-
} catch {
|
|
2272
|
-
throw new Error("Invalidation commit metadata is invalid.");
|
|
2273
|
-
}
|
|
2274
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2275
|
-
throw new Error("Invalidation commit metadata is invalid.");
|
|
2276
|
-
}
|
|
2277
|
-
const root = parsed;
|
|
2278
|
-
if (Object.keys(root).sort().join(",") !== "commits,version" || root.version !== 1 || !Array.isArray(root.commits)) {
|
|
2279
|
-
throw new Error("Invalidation commit metadata is invalid.");
|
|
2280
|
-
}
|
|
2281
|
-
const commits = /* @__PURE__ */ new Map();
|
|
2282
|
-
for (const rawEntry of root.commits) {
|
|
2283
|
-
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) {
|
|
2284
|
-
throw new Error("Invalidation commit metadata is invalid.");
|
|
2285
|
-
}
|
|
2286
|
-
const entry = rawEntry;
|
|
2287
|
-
if (Object.keys(entry).sort().join(",") !== "committedAt,fingerprint,memoryId" || !isValidMemoryId(entry.memoryId) || !isValidInvalidationCommitFingerprint(entry.fingerprint) || !isValidInvalidationCommitTimestamp(entry.committedAt) || commits.has(entry.memoryId)) {
|
|
2288
|
-
throw new Error("Invalidation commit metadata is invalid.");
|
|
2289
|
-
}
|
|
2290
|
-
commits.set(entry.memoryId, {
|
|
2291
|
-
fingerprint: entry.fingerprint,
|
|
2292
|
-
committedAt: entry.committedAt
|
|
2293
|
-
});
|
|
2294
|
-
}
|
|
2295
|
-
return commits;
|
|
2296
|
-
}
|
|
2297
|
-
async readInvalidationCommitMetadata() {
|
|
2298
|
-
const metadataPath = await this.resolveConfiguredStoragePath(this.options.invalidationCommitMetadataPath);
|
|
2299
|
-
let raw;
|
|
2300
|
-
try {
|
|
2301
|
-
raw = await readFile(metadataPath, "utf8");
|
|
2302
|
-
} catch (error) {
|
|
2303
|
-
if (isErrnoCode(error, "ENOENT")) return /* @__PURE__ */ new Map();
|
|
2304
|
-
throw new Error("Invalidation commit metadata is unavailable.");
|
|
2305
|
-
}
|
|
2306
|
-
return this.parseInvalidationCommitMetadata(raw);
|
|
2307
|
-
}
|
|
2308
|
-
async writeInvalidationCommitMetadata(commits, lock) {
|
|
2309
|
-
const metadataPath = await this.resolveConfiguredStoragePath(this.options.invalidationCommitMetadataPath);
|
|
2310
|
-
const entries = [...commits.entries()].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([memoryId, value]) => ({
|
|
2311
|
-
memoryId,
|
|
2312
|
-
fingerprint: value.fingerprint,
|
|
2313
|
-
committedAt: value.committedAt
|
|
2314
|
-
}));
|
|
2315
|
-
const metadata = { version: 1, commits: entries };
|
|
2316
|
-
const temporaryPath = await this.resolveConfiguredStoragePath(
|
|
2317
|
-
`${metadataPath}.${process.pid}.${randomUUID()}.tmp`
|
|
2318
|
-
);
|
|
2319
|
-
const metadataDir = await this.resolveConfiguredStoragePath(path3.dirname(metadataPath));
|
|
2320
|
-
let handle = null;
|
|
2321
|
-
let renamed = false;
|
|
2322
|
-
try {
|
|
2323
|
-
await mkdir(metadataDir, { recursive: true });
|
|
2324
|
-
handle = await open(temporaryPath, "wx", 384);
|
|
2325
|
-
await handle.writeFile(`${JSON.stringify(metadata)}
|
|
2326
|
-
`, "utf8");
|
|
2327
|
-
await handle.sync();
|
|
2328
|
-
await handle.close();
|
|
2329
|
-
handle = null;
|
|
2330
|
-
if (!await lock.refresh()) {
|
|
2331
|
-
throw new Error("Invalidation commit metadata lock was lost.");
|
|
2332
|
-
}
|
|
2333
|
-
const renameTarget = await this.resolveConfiguredStoragePath(this.options.invalidationCommitMetadataPath);
|
|
2334
|
-
await rename(temporaryPath, renameTarget);
|
|
2335
|
-
renamed = true;
|
|
2336
|
-
} finally {
|
|
2337
|
-
if (handle !== null) {
|
|
2338
|
-
await handle.close().catch((error) => {
|
|
2339
|
-
log.warn("failed to close invalidation commit metadata temporary file", error);
|
|
2340
|
-
});
|
|
2341
|
-
}
|
|
2342
|
-
const cleanupPath = await this.resolveConfiguredStoragePath(temporaryPath).catch((error) => {
|
|
2343
|
-
log.warn("failed to resolve invalidation commit metadata temporary file for cleanup", error);
|
|
2344
|
-
return null;
|
|
2345
|
-
});
|
|
2346
|
-
if (cleanupPath !== null) {
|
|
2347
|
-
await unlink2(cleanupPath).catch((error) => {
|
|
2348
|
-
if (!isErrnoCode(error, "ENOENT")) {
|
|
2349
|
-
log.warn(
|
|
2350
|
-
`failed to clean up invalidation commit metadata temporary file after ${renamed ? "commit" : "failure"}`,
|
|
2351
|
-
error
|
|
2352
|
-
);
|
|
2353
|
-
}
|
|
2354
|
-
});
|
|
2355
|
-
}
|
|
2356
|
-
}
|
|
2357
|
-
}
|
|
2358
|
-
async hasCommittedInvalidation(memory) {
|
|
2359
|
-
const memoryId = memory.frontmatter.id;
|
|
2360
|
-
const fingerprint = invalidationCommitFingerprint(memory);
|
|
2361
|
-
return this.withDeletionRevisionLock(async () => {
|
|
2362
|
-
const entry = (await this.readInvalidationCommitMetadata()).get(memoryId);
|
|
2363
|
-
if (entry?.fingerprint !== fingerprint) return false;
|
|
2364
|
-
if (this.invalidationProofQuarantine.has(memoryId)) return false;
|
|
2365
|
-
if (!this.invalidationProofQuarantineFull) return true;
|
|
2366
|
-
const fullAt = this.invalidationProofQuarantineFullAt;
|
|
2367
|
-
return fullAt !== null && entry.committedAt >= fullAt;
|
|
2368
|
-
});
|
|
2369
|
-
}
|
|
2370
|
-
async recordCommittedInvalidation(memory) {
|
|
2371
|
-
const fingerprint = invalidationCommitFingerprint(memory);
|
|
2372
|
-
await this.withDeletionRevisionLock(async (lock) => {
|
|
2373
|
-
const fullAt = this.invalidationProofQuarantineFullAt;
|
|
2374
|
-
const committedAt = fullAt === null ? Date.now() : Math.max(Date.now(), fullAt + 1);
|
|
2375
|
-
const commits = await this.readInvalidationCommitMetadata();
|
|
2376
|
-
commits.set(memory.frontmatter.id, {
|
|
2377
|
-
fingerprint,
|
|
2378
|
-
committedAt
|
|
2379
|
-
});
|
|
2380
|
-
await this.writeInvalidationCommitMetadata(commits, lock);
|
|
2381
|
-
this.invalidationProofQuarantine.delete(memory.frontmatter.id);
|
|
2382
|
-
});
|
|
2383
|
-
}
|
|
2384
|
-
async clearCommittedInvalidation(memory) {
|
|
2385
|
-
const memoryId = memory.frontmatter.id;
|
|
2386
|
-
this.quarantineInvalidationProof(memoryId);
|
|
2387
|
-
const fingerprint = invalidationCommitFingerprint(memory);
|
|
2388
|
-
let cleared = false;
|
|
2389
|
-
try {
|
|
2390
|
-
await this.withDeletionRevisionLock(async (lock) => {
|
|
2391
|
-
const commits = await this.readInvalidationCommitMetadata();
|
|
2392
|
-
const current = commits.get(memoryId);
|
|
2393
|
-
if (current?.fingerprint !== fingerprint) return;
|
|
2394
|
-
commits.delete(memoryId);
|
|
2395
|
-
await this.writeInvalidationCommitMetadata(commits, lock);
|
|
2396
|
-
});
|
|
2397
|
-
cleared = true;
|
|
2398
|
-
} finally {
|
|
2399
|
-
if (cleared) this.invalidationProofQuarantine.delete(memoryId);
|
|
2400
|
-
}
|
|
2401
|
-
}
|
|
2402
|
-
async recordReplicatedDeletionRevision(filePath, mtimeMs) {
|
|
2403
|
-
const { relativePath } = await this.resolveManagedStoragePath(
|
|
2404
|
-
filePath,
|
|
2405
|
-
"storage.recordReplicatedDeletionRevision"
|
|
2406
|
-
);
|
|
2407
|
-
if (typeof mtimeMs !== "number" || !Number.isFinite(mtimeMs) || mtimeMs < 0 || mtimeMs > DELETION_REVISION_MAX_MTIME_MS) {
|
|
2408
|
-
throw new Error("Deletion revision timestamp is invalid.");
|
|
2409
|
-
}
|
|
2410
|
-
if (!isValidDeletionRevisionPath(relativePath)) {
|
|
2411
|
-
throw new Error("Deletion revision path is invalid.");
|
|
2412
|
-
}
|
|
2413
|
-
await this.withDeletionRevisionLock(async (lock) => {
|
|
2414
|
-
const revisions = await this.readDeletionRevisionMetadata();
|
|
2415
|
-
const identity = deletionRevisionPathIdentity(relativePath);
|
|
2416
|
-
let existingPath;
|
|
2417
|
-
for (const candidatePath of revisions.keys()) {
|
|
2418
|
-
if (deletionRevisionPathIdentity(candidatePath) === identity) {
|
|
2419
|
-
existingPath = candidatePath;
|
|
2420
|
-
break;
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2423
|
-
const existingMtimeMs = existingPath === void 0 ? void 0 : revisions.get(existingPath);
|
|
2424
|
-
if (existingMtimeMs !== void 0 && existingMtimeMs >= mtimeMs) return;
|
|
2425
|
-
const updated = new Map(revisions);
|
|
2426
|
-
if (existingPath !== void 0) updated.delete(existingPath);
|
|
2427
|
-
updated.set(relativePath, mtimeMs);
|
|
2428
|
-
await this.writeDeletionRevisionMetadata(updated, lock);
|
|
2429
|
-
});
|
|
2430
|
-
}
|
|
2431
|
-
async writeManagedStorageFile(filePath, write) {
|
|
2432
|
-
const { relativePath } = await this.resolveManagedStoragePath(filePath, "storage.writeManagedStorageFile");
|
|
2433
|
-
if (!isValidDeletionRevisionPath(relativePath)) {
|
|
2434
|
-
throw new Error("Deletion revision path is invalid.");
|
|
2435
|
-
}
|
|
2436
|
-
await this.withDeletionRevisionLock(async (lock) => {
|
|
2437
|
-
const before = await this.readDeletionRevisionMetadata();
|
|
2438
|
-
const identity = deletionRevisionPathIdentity(relativePath);
|
|
2439
|
-
const existingPath = [...before.keys()].find(
|
|
2440
|
-
(candidatePath) => deletionRevisionPathIdentity(candidatePath) === identity
|
|
2441
|
-
);
|
|
2442
|
-
await write();
|
|
2443
|
-
if (existingPath === void 0) return;
|
|
2444
|
-
const updated = new Map(before);
|
|
2445
|
-
updated.delete(existingPath);
|
|
2446
|
-
await this.writeDeletionRevisionMetadata(updated, lock);
|
|
2447
|
-
});
|
|
2448
|
-
}
|
|
2449
|
-
async deleteManagedStorageFile(filePath, deletionMtimeMs) {
|
|
2450
|
-
const { target, relativePath } = await this.resolveManagedStoragePath(
|
|
2451
|
-
filePath,
|
|
2452
|
-
"storage.deleteManagedStorageFile"
|
|
2453
|
-
);
|
|
2454
|
-
if (deletionMtimeMs !== void 0 && deletionMtimeMs !== null && (typeof deletionMtimeMs !== "number" || !Number.isFinite(deletionMtimeMs) || deletionMtimeMs < 0 || deletionMtimeMs > DELETION_REVISION_MAX_MTIME_MS)) {
|
|
2455
|
-
throw new Error("Deletion revision timestamp is invalid.");
|
|
2456
|
-
}
|
|
2457
|
-
return this.withDeletionRevisionLock(async (lock) => {
|
|
2458
|
-
const safeTarget = await this.resolveConfiguredStoragePath(target);
|
|
2459
|
-
try {
|
|
2460
|
-
await lstat2(safeTarget);
|
|
2461
|
-
} catch (error) {
|
|
2462
|
-
if (isErrnoCode(error, "ENOENT")) return false;
|
|
2463
|
-
throw error;
|
|
2464
|
-
}
|
|
2465
|
-
if (!isValidDeletionRevisionPath(relativePath)) {
|
|
2466
|
-
throw new Error("Deletion revision path is invalid.");
|
|
2467
|
-
}
|
|
2468
|
-
const revision = deletionMtimeMs === null ? void 0 : deletionMtimeMs ?? Date.now();
|
|
2469
|
-
const before = await this.readDeletionRevisionMetadata();
|
|
2470
|
-
const identity = deletionRevisionPathIdentity(relativePath);
|
|
2471
|
-
let existingPath;
|
|
2472
|
-
for (const candidatePath of before.keys()) {
|
|
2473
|
-
if (deletionRevisionPathIdentity(candidatePath) === identity) {
|
|
2474
|
-
existingPath = candidatePath;
|
|
2475
|
-
break;
|
|
2476
|
-
}
|
|
2477
|
-
}
|
|
2478
|
-
const existing = existingPath === void 0 ? void 0 : before.get(existingPath);
|
|
2479
|
-
const changed = existingPath !== void 0 && existingPath !== relativePath || (revision === void 0 ? existing !== void 0 : existing !== revision);
|
|
2480
|
-
if (changed) {
|
|
2481
|
-
const updated = new Map(before);
|
|
2482
|
-
if (existingPath !== void 0) updated.delete(existingPath);
|
|
2483
|
-
if (revision !== void 0) updated.set(relativePath, revision);
|
|
2484
|
-
await this.writeDeletionRevisionMetadata(updated, lock);
|
|
2485
|
-
}
|
|
2486
|
-
try {
|
|
2487
|
-
const unlinkTarget = await this.resolveConfiguredStoragePath(target);
|
|
2488
|
-
await unlink2(unlinkTarget);
|
|
2489
|
-
return true;
|
|
2490
|
-
} catch (error) {
|
|
2491
|
-
if (changed) await this.writeDeletionRevisionMetadata(before, lock);
|
|
2492
|
-
if (isErrnoCode(error, "ENOENT")) return false;
|
|
2493
|
-
throw error;
|
|
2494
|
-
}
|
|
2495
|
-
});
|
|
2496
|
-
}
|
|
2497
|
-
};
|
|
2498
|
-
|
|
2499
2092
|
// src/storage/identity-continuity-store.ts
|
|
2500
2093
|
import { readdir as readdir3 } from "fs/promises";
|
|
2501
|
-
import
|
|
2094
|
+
import path3 from "path";
|
|
2502
2095
|
var IdentityContinuityStore = class {
|
|
2503
2096
|
constructor(deps) {
|
|
2504
2097
|
this.deps = deps;
|
|
@@ -2523,7 +2116,7 @@ var IdentityContinuityStore = class {
|
|
|
2523
2116
|
const date = nowIso.slice(0, 10);
|
|
2524
2117
|
const id = this.deps.generateId("incident");
|
|
2525
2118
|
const incident = createContinuityIncidentRecord(id, input, nowIso);
|
|
2526
|
-
const filePath =
|
|
2119
|
+
const filePath = path3.join(this.deps.identityIncidentsDir, `${date}-${id}.md`);
|
|
2527
2120
|
await this.deps.writeStorageSecureFile(filePath, serializeContinuityIncident(incident));
|
|
2528
2121
|
return { ...incident, filePath };
|
|
2529
2122
|
}
|
|
@@ -2536,7 +2129,7 @@ var IdentityContinuityStore = class {
|
|
|
2536
2129
|
const incidents = [];
|
|
2537
2130
|
for (const file of candidates) {
|
|
2538
2131
|
if (incidents.length >= cappedLimit) break;
|
|
2539
|
-
const filePath =
|
|
2132
|
+
const filePath = path3.join(this.deps.identityIncidentsDir, file);
|
|
2540
2133
|
try {
|
|
2541
2134
|
const raw = await this.deps.readStorageSecureFile(filePath);
|
|
2542
2135
|
const parsed = parseContinuityIncident(raw);
|
|
@@ -2567,7 +2160,7 @@ var IdentityContinuityStore = class {
|
|
|
2567
2160
|
await this.deps.ensureDirectories();
|
|
2568
2161
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2569
2162
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2570
|
-
const filePath =
|
|
2163
|
+
const filePath = path3.join(dir, `${safeKey}.md`);
|
|
2571
2164
|
await this.deps.writeStorageSecureFile(filePath, content);
|
|
2572
2165
|
return filePath;
|
|
2573
2166
|
}
|
|
@@ -2575,7 +2168,7 @@ var IdentityContinuityStore = class {
|
|
|
2575
2168
|
try {
|
|
2576
2169
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2577
2170
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2578
|
-
return await this.deps.readStorageSecureFile(
|
|
2171
|
+
return await this.deps.readStorageSecureFile(path3.join(dir, `${safeKey}.md`));
|
|
2579
2172
|
} catch (err) {
|
|
2580
2173
|
if (err instanceof Error && err.message === "Invalid identity audit key") return null;
|
|
2581
2174
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -2631,12 +2224,12 @@ var IdentityContinuityStore = class {
|
|
|
2631
2224
|
const fileNames = await this.readContinuityIncidentFileNames();
|
|
2632
2225
|
const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));
|
|
2633
2226
|
if (directMatch) {
|
|
2634
|
-
const directPath =
|
|
2227
|
+
const directPath = path3.join(this.deps.identityIncidentsDir, directMatch);
|
|
2635
2228
|
const parsed = await this.readContinuityIncidentFile(directPath);
|
|
2636
2229
|
if (parsed?.id === id) return directPath;
|
|
2637
2230
|
}
|
|
2638
2231
|
for (const fileName of fileNames) {
|
|
2639
|
-
const filePath =
|
|
2232
|
+
const filePath = path3.join(this.deps.identityIncidentsDir, fileName);
|
|
2640
2233
|
const parsed = await this.readContinuityIncidentFile(filePath);
|
|
2641
2234
|
if (parsed?.id === id) return filePath;
|
|
2642
2235
|
}
|
|
@@ -2652,19 +2245,19 @@ var IdentityContinuityStore = class {
|
|
|
2652
2245
|
};
|
|
2653
2246
|
|
|
2654
2247
|
// src/storage/entity-canonical-id-migration.ts
|
|
2655
|
-
import { createHash
|
|
2248
|
+
import { createHash, randomUUID } from "crypto";
|
|
2656
2249
|
import {
|
|
2657
2250
|
access,
|
|
2658
|
-
lstat as
|
|
2659
|
-
readFile
|
|
2251
|
+
lstat as lstat2,
|
|
2252
|
+
readFile,
|
|
2660
2253
|
readdir as readdir4,
|
|
2661
2254
|
realpath as realpath2,
|
|
2662
|
-
rename
|
|
2255
|
+
rename,
|
|
2663
2256
|
stat as statFile,
|
|
2664
|
-
unlink as
|
|
2257
|
+
unlink as unlink2,
|
|
2665
2258
|
writeFile
|
|
2666
2259
|
} from "fs/promises";
|
|
2667
|
-
import
|
|
2260
|
+
import path4 from "path";
|
|
2668
2261
|
import { z } from "zod";
|
|
2669
2262
|
var ENTITY_CANONICAL_ID_MIGRATION_VERSION = 1;
|
|
2670
2263
|
var ENTITY_CANONICAL_ID_MIGRATION_LOCK_STALE_MS = 6e4;
|
|
@@ -2689,7 +2282,7 @@ var EntityCanonicalIdMigrationStateSchema = z.object({
|
|
|
2689
2282
|
async function fingerprintPath(filePath) {
|
|
2690
2283
|
let fileStat;
|
|
2691
2284
|
try {
|
|
2692
|
-
fileStat = await
|
|
2285
|
+
fileStat = await lstat2(filePath);
|
|
2693
2286
|
} catch (error) {
|
|
2694
2287
|
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
2695
2288
|
}
|
|
@@ -2698,16 +2291,16 @@ async function fingerprintPath(filePath) {
|
|
|
2698
2291
|
async function fingerprintEntityEntries(entitiesDir) {
|
|
2699
2292
|
let names;
|
|
2700
2293
|
try {
|
|
2701
|
-
names = (await readdir4(entitiesDir)).filter((name) =>
|
|
2294
|
+
names = (await readdir4(entitiesDir)).filter((name) => path4.extname(name) === ".md").sort();
|
|
2702
2295
|
} catch (error) {
|
|
2703
2296
|
if (isErrnoCode(error, "ENOENT")) return "missing";
|
|
2704
2297
|
throw error;
|
|
2705
2298
|
}
|
|
2706
|
-
const hash =
|
|
2299
|
+
const hash = createHash("sha256");
|
|
2707
2300
|
for (const name of names) {
|
|
2708
2301
|
hash.update(`${name.length}:${name}:`);
|
|
2709
2302
|
try {
|
|
2710
|
-
const entry = await
|
|
2303
|
+
const entry = await lstat2(path4.join(entitiesDir, name), { bigint: true });
|
|
2711
2304
|
hash.update(`${entry.dev}:${entry.ino}:${entry.size}:${entry.mtimeNs}:${entry.ctimeNs}`);
|
|
2712
2305
|
} catch (error) {
|
|
2713
2306
|
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
@@ -2727,9 +2320,9 @@ async function getFingerprint(baseDir, entitiesDir, getEntityMutationVersion) {
|
|
|
2727
2320
|
] = await Promise.all([
|
|
2728
2321
|
fingerprintPath(entitiesDir),
|
|
2729
2322
|
fingerprintEntityEntries(entitiesDir),
|
|
2730
|
-
fingerprintPath(
|
|
2731
|
-
fingerprintPath(
|
|
2732
|
-
fingerprintPath(
|
|
2323
|
+
fingerprintPath(path4.join(baseDir, "config", "aliases.json")),
|
|
2324
|
+
fingerprintPath(path4.join(baseDir, "state", ENTITY_CANONICAL_ID_RECONCILE_MARKER)),
|
|
2325
|
+
fingerprintPath(path4.join(baseDir, "state", ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER))
|
|
2733
2326
|
]);
|
|
2734
2327
|
return [
|
|
2735
2328
|
entityDirectoryFingerprint,
|
|
@@ -2743,7 +2336,7 @@ async function getFingerprint(baseDir, entitiesDir, getEntityMutationVersion) {
|
|
|
2743
2336
|
async function validateRoots(baseDir, entitiesDir, stateDir, archiveDir) {
|
|
2744
2337
|
let baseStat;
|
|
2745
2338
|
try {
|
|
2746
|
-
baseStat = await
|
|
2339
|
+
baseStat = await lstat2(baseDir);
|
|
2747
2340
|
} catch (error) {
|
|
2748
2341
|
if (isErrnoCode(error, "ENOENT")) return;
|
|
2749
2342
|
throw error;
|
|
@@ -2755,14 +2348,14 @@ async function validateRoots(baseDir, entitiesDir, stateDir, archiveDir) {
|
|
|
2755
2348
|
const roots = [
|
|
2756
2349
|
entitiesDir,
|
|
2757
2350
|
stateDir,
|
|
2758
|
-
...RECALL_FALLBACK_DIRS.map((directory) =>
|
|
2759
|
-
|
|
2351
|
+
...RECALL_FALLBACK_DIRS.map((directory) => path4.join(baseDir, directory)),
|
|
2352
|
+
path4.join(baseDir, "cold"),
|
|
2760
2353
|
archiveDir
|
|
2761
2354
|
];
|
|
2762
2355
|
for (const root of roots) {
|
|
2763
2356
|
let rootStat;
|
|
2764
2357
|
try {
|
|
2765
|
-
rootStat = await
|
|
2358
|
+
rootStat = await lstat2(root);
|
|
2766
2359
|
} catch (error) {
|
|
2767
2360
|
if (isErrnoCode(error, "ENOENT")) continue;
|
|
2768
2361
|
throw error;
|
|
@@ -2774,13 +2367,13 @@ async function validateRoots(baseDir, entitiesDir, stateDir, archiveDir) {
|
|
|
2774
2367
|
}
|
|
2775
2368
|
}
|
|
2776
2369
|
function statePath(deps) {
|
|
2777
|
-
return
|
|
2370
|
+
return path4.join(deps.stateDir, ENTITY_CANONICAL_ID_MIGRATION_FILE);
|
|
2778
2371
|
}
|
|
2779
2372
|
async function assertSafeMigrationStateFile(deps) {
|
|
2780
2373
|
const migrationStatePath = statePath(deps);
|
|
2781
2374
|
let fileStat;
|
|
2782
2375
|
try {
|
|
2783
|
-
fileStat = await
|
|
2376
|
+
fileStat = await lstat2(migrationStatePath);
|
|
2784
2377
|
} catch (error) {
|
|
2785
2378
|
if (isErrnoCode(error, "ENOENT")) return;
|
|
2786
2379
|
throw error;
|
|
@@ -2799,7 +2392,7 @@ async function assertSafeMigrationStateFile(deps) {
|
|
|
2799
2392
|
async function assertSafeTombstoneFile(deps, tombstonePath) {
|
|
2800
2393
|
let fileStat;
|
|
2801
2394
|
try {
|
|
2802
|
-
fileStat = await
|
|
2395
|
+
fileStat = await lstat2(tombstonePath);
|
|
2803
2396
|
} catch (error) {
|
|
2804
2397
|
if (isErrnoCode(error, "ENOENT")) return false;
|
|
2805
2398
|
throw error;
|
|
@@ -2817,13 +2410,13 @@ async function assertSafeTombstoneFile(deps, tombstonePath) {
|
|
|
2817
2410
|
return true;
|
|
2818
2411
|
}
|
|
2819
2412
|
function lockPath(deps) {
|
|
2820
|
-
return
|
|
2413
|
+
return path4.join(deps.stateDir, "entity-canonical-id-migration.lock");
|
|
2821
2414
|
}
|
|
2822
2415
|
async function readState(deps) {
|
|
2823
2416
|
await assertSafeMigrationStateFile(deps);
|
|
2824
2417
|
let raw;
|
|
2825
2418
|
try {
|
|
2826
|
-
raw = await
|
|
2419
|
+
raw = await readFile(statePath(deps), "utf-8");
|
|
2827
2420
|
} catch (error) {
|
|
2828
2421
|
if (isErrnoCode(error, "ENOENT")) return null;
|
|
2829
2422
|
throw error;
|
|
@@ -2846,13 +2439,13 @@ async function readState(deps) {
|
|
|
2846
2439
|
}
|
|
2847
2440
|
async function writeState(deps, state) {
|
|
2848
2441
|
const destination = statePath(deps);
|
|
2849
|
-
const temporary = `${destination}.${process.pid}.${
|
|
2442
|
+
const temporary = `${destination}.${process.pid}.${randomUUID()}.tmp`;
|
|
2850
2443
|
try {
|
|
2851
2444
|
await writeFile(temporary, `${JSON.stringify(state, null, 2)}
|
|
2852
2445
|
`, "utf-8");
|
|
2853
|
-
await
|
|
2446
|
+
await rename(temporary, destination);
|
|
2854
2447
|
} finally {
|
|
2855
|
-
await
|
|
2448
|
+
await unlink2(temporary).catch(() => void 0);
|
|
2856
2449
|
}
|
|
2857
2450
|
}
|
|
2858
2451
|
async function publishState(deps, state) {
|
|
@@ -2881,7 +2474,7 @@ async function sameFileIdentity(leftPath, rightPath) {
|
|
|
2881
2474
|
async function assertNotSymlink(filePath, label) {
|
|
2882
2475
|
let stat3;
|
|
2883
2476
|
try {
|
|
2884
|
-
stat3 = await
|
|
2477
|
+
stat3 = await lstat2(filePath);
|
|
2885
2478
|
} catch (error) {
|
|
2886
2479
|
if (isErrnoCode(error, "ENOENT")) return;
|
|
2887
2480
|
throw error;
|
|
@@ -2893,7 +2486,7 @@ async function assertNotSymlink(filePath, label) {
|
|
|
2893
2486
|
async function assertNotMemorySymlink(filePath) {
|
|
2894
2487
|
let stat3;
|
|
2895
2488
|
try {
|
|
2896
|
-
stat3 = await
|
|
2489
|
+
stat3 = await lstat2(filePath);
|
|
2897
2490
|
} catch (error) {
|
|
2898
2491
|
if (isErrnoCode(error, "ENOENT")) return;
|
|
2899
2492
|
throw error;
|
|
@@ -2909,13 +2502,13 @@ async function assertEntityContentUnchanged(deps, filePath, expectedContent, leg
|
|
|
2909
2502
|
}
|
|
2910
2503
|
}
|
|
2911
2504
|
async function readSafeEntityEntries(entitiesDir) {
|
|
2912
|
-
const rootStat = await
|
|
2505
|
+
const rootStat = await lstat2(entitiesDir);
|
|
2913
2506
|
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
|
|
2914
2507
|
throw new Error("Refusing entity canonical-id migration through a symlinked or non-directory entities root.");
|
|
2915
2508
|
}
|
|
2916
2509
|
const entries = await readdir4(entitiesDir);
|
|
2917
2510
|
for (const entry of entries) {
|
|
2918
|
-
await assertNotSymlink(
|
|
2511
|
+
await assertNotSymlink(path4.join(entitiesDir, entry), entry);
|
|
2919
2512
|
}
|
|
2920
2513
|
return entries;
|
|
2921
2514
|
}
|
|
@@ -2977,7 +2570,7 @@ async function rewriteReferences(deps, mappings, refreshLock) {
|
|
|
2977
2570
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
2978
2571
|
let rewroteAny = false;
|
|
2979
2572
|
for (const memory of [...hotMemories, ...coldMemories, ...archivedMemories]) {
|
|
2980
|
-
const memoryPath =
|
|
2573
|
+
const memoryPath = path4.resolve(memory.path);
|
|
2981
2574
|
if (seenPaths.has(memoryPath)) continue;
|
|
2982
2575
|
seenPaths.add(memoryPath);
|
|
2983
2576
|
const previousEntityRef = memory.frontmatter.entityRef;
|
|
@@ -3009,7 +2602,7 @@ async function rewriteReferences(deps, mappings, refreshLock) {
|
|
|
3009
2602
|
latestCanonicalId
|
|
3010
2603
|
);
|
|
3011
2604
|
rewroteAny = true;
|
|
3012
|
-
rewroteColdMemory ||= latestMemory.path.includes(`${
|
|
2605
|
+
rewroteColdMemory ||= latestMemory.path.includes(`${path4.sep}cold${path4.sep}`);
|
|
3013
2606
|
}
|
|
3014
2607
|
if (!rewroteAny) return { rewroteColdMemory };
|
|
3015
2608
|
}
|
|
@@ -3048,7 +2641,7 @@ function rewriteTombstoneLine(line, mappings, normalizedMappings) {
|
|
|
3048
2641
|
return changed ? JSON.stringify(tombstone) : line;
|
|
3049
2642
|
}
|
|
3050
2643
|
async function rewriteTombstoneReferences(deps, mappings, refreshLock) {
|
|
3051
|
-
const tombstonePath =
|
|
2644
|
+
const tombstonePath = path4.join(deps.stateDir, "tombstones.jsonl");
|
|
3052
2645
|
const normalizedMappings = /* @__PURE__ */ new Map();
|
|
3053
2646
|
for (const [legacyId, canonicalId] of Object.entries(mappings)) {
|
|
3054
2647
|
const normalizedLegacyId = normalizeSupersessionKey(legacyId);
|
|
@@ -3057,7 +2650,7 @@ async function rewriteTombstoneReferences(deps, mappings, refreshLock) {
|
|
|
3057
2650
|
}
|
|
3058
2651
|
}
|
|
3059
2652
|
await withHeldFileLock(
|
|
3060
|
-
|
|
2653
|
+
path4.join(deps.stateDir, "tombstones.lock"),
|
|
3061
2654
|
{
|
|
3062
2655
|
staleMs: TOMBSTONE_LOCK_STALE_MS,
|
|
3063
2656
|
maxWaitMs: TOMBSTONE_LOCK_MAX_WAIT_MS
|
|
@@ -3245,7 +2838,7 @@ async function migrateEntityFilePair(deps, legacyId, canonicalId, refreshMigrati
|
|
|
3245
2838
|
await deps.snapshotBeforeWrite(legacyPath, "write");
|
|
3246
2839
|
await assertNotSymlink(legacyPath, legacyId);
|
|
3247
2840
|
await assertEntityContentUnchanged(deps, legacyPath, legacyContent, legacyId);
|
|
3248
|
-
await
|
|
2841
|
+
await unlink2(legacyPath);
|
|
3249
2842
|
return { deferred: false, progressed: true };
|
|
3250
2843
|
}
|
|
3251
2844
|
if (!legacyExists) return { deferred: false, progressed: false };
|
|
@@ -3269,13 +2862,13 @@ async function migrateEntityFilePair(deps, legacyId, canonicalId, refreshMigrati
|
|
|
3269
2862
|
await deps.snapshotBeforeWrite(legacyPath, "write");
|
|
3270
2863
|
await assertNotSymlink(legacyPath, legacyId);
|
|
3271
2864
|
await assertEntityContentUnchanged(deps, legacyPath, entityContent, legacyId);
|
|
3272
|
-
await
|
|
2865
|
+
await unlink2(legacyPath);
|
|
3273
2866
|
} catch (error) {
|
|
3274
2867
|
if (!canonicalExists && canonicalFingerprintAfterWrite !== null) {
|
|
3275
2868
|
try {
|
|
3276
2869
|
if (await fingerprintPath(canonicalPath) === canonicalFingerprintAfterWrite) {
|
|
3277
2870
|
await assertNotSymlink(canonicalPath, canonicalId);
|
|
3278
|
-
await
|
|
2871
|
+
await unlink2(canonicalPath);
|
|
3279
2872
|
}
|
|
3280
2873
|
} catch {
|
|
3281
2874
|
}
|
|
@@ -3296,12 +2889,12 @@ async function migrateLegacyEntityCanonicalIds(deps) {
|
|
|
3296
2889
|
if (!acquired) throw new Error("Timed out waiting for active entity canonical-id migration.");
|
|
3297
2890
|
await deps.validateMemoryScanRoots?.();
|
|
3298
2891
|
await readSafeEntityEntries(deps.entitiesDir);
|
|
3299
|
-
const reconcileMarkerPath =
|
|
3300
|
-
const consumingMarkerPath =
|
|
2892
|
+
const reconcileMarkerPath = path4.join(deps.stateDir, ENTITY_CANONICAL_ID_RECONCILE_MARKER);
|
|
2893
|
+
const consumingMarkerPath = path4.join(deps.stateDir, ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER);
|
|
3301
2894
|
let reconcileRequested = await fileExists(consumingMarkerPath);
|
|
3302
2895
|
if (await fileExists(reconcileMarkerPath)) {
|
|
3303
2896
|
try {
|
|
3304
|
-
await
|
|
2897
|
+
await rename(reconcileMarkerPath, consumingMarkerPath);
|
|
3305
2898
|
reconcileRequested = true;
|
|
3306
2899
|
} catch (error) {
|
|
3307
2900
|
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
@@ -3324,7 +2917,7 @@ async function migrateLegacyEntityCanonicalIds(deps) {
|
|
|
3324
2917
|
);
|
|
3325
2918
|
}
|
|
3326
2919
|
if (reconcileRequested) {
|
|
3327
|
-
await
|
|
2920
|
+
await unlink2(consumingMarkerPath).catch((error) => {
|
|
3328
2921
|
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
3329
2922
|
});
|
|
3330
2923
|
}
|
|
@@ -3470,7 +3063,7 @@ async function migrateLegacyEntityCanonicalIds(deps) {
|
|
|
3470
3063
|
}
|
|
3471
3064
|
|
|
3472
3065
|
// src/storage/entity-ref-repair.ts
|
|
3473
|
-
import { unlink as
|
|
3066
|
+
import { unlink as unlink3 } from "fs/promises";
|
|
3474
3067
|
var EntityRefRepair = class {
|
|
3475
3068
|
constructor(deps) {
|
|
3476
3069
|
this.deps = deps;
|
|
@@ -3532,7 +3125,7 @@ ${body}
|
|
|
3532
3125
|
if (opts.onFailRestore) {
|
|
3533
3126
|
await this.restore(opts.onFailRestore);
|
|
3534
3127
|
} else if (opts.onFailRemove) {
|
|
3535
|
-
await
|
|
3128
|
+
await unlink3(opts.onFailRemove).catch(() => void 0);
|
|
3536
3129
|
this.deps.invalidateAllMemoriesCache();
|
|
3537
3130
|
}
|
|
3538
3131
|
throw err;
|
|
@@ -3693,7 +3286,7 @@ import {
|
|
|
3693
3286
|
readFileSync,
|
|
3694
3287
|
realpathSync
|
|
3695
3288
|
} from "fs";
|
|
3696
|
-
import
|
|
3289
|
+
import path5 from "path";
|
|
3697
3290
|
function resolveSafeAliasRoots(baseDir, configDir) {
|
|
3698
3291
|
let baseStat;
|
|
3699
3292
|
try {
|
|
@@ -3720,8 +3313,8 @@ function resolveSafeAliasRoots(baseDir, configDir) {
|
|
|
3720
3313
|
return memoryRoot;
|
|
3721
3314
|
}
|
|
3722
3315
|
function readEntityAliasConfigSync(baseDir) {
|
|
3723
|
-
const configDir =
|
|
3724
|
-
const aliasPath =
|
|
3316
|
+
const configDir = path5.join(baseDir, "config");
|
|
3317
|
+
const aliasPath = path5.join(configDir, "aliases.json");
|
|
3725
3318
|
let memoryRoot = resolveSafeAliasRoots(baseDir, configDir);
|
|
3726
3319
|
if (memoryRoot === void 0) return void 0;
|
|
3727
3320
|
let aliasPreflight;
|
|
@@ -3782,9 +3375,40 @@ function decodeYamlScalar(value) {
|
|
|
3782
3375
|
}
|
|
3783
3376
|
|
|
3784
3377
|
// src/orchestration/qmd-result-resolver.ts
|
|
3785
|
-
import
|
|
3378
|
+
import path6 from "path";
|
|
3379
|
+
var INTERNAL_QMD_ROOTS = /* @__PURE__ */ new Set([
|
|
3380
|
+
...ALL_CATEGORY_DIRS,
|
|
3381
|
+
"activity",
|
|
3382
|
+
"archive",
|
|
3383
|
+
"artifacts",
|
|
3384
|
+
"cold",
|
|
3385
|
+
"config",
|
|
3386
|
+
"entities",
|
|
3387
|
+
"identity",
|
|
3388
|
+
"meetings",
|
|
3389
|
+
"namespaces",
|
|
3390
|
+
"state",
|
|
3391
|
+
"summaries",
|
|
3392
|
+
"transcripts",
|
|
3393
|
+
"wearables",
|
|
3394
|
+
"work",
|
|
3395
|
+
"workspace"
|
|
3396
|
+
]);
|
|
3397
|
+
var PRIVATE_RESULT_RESOLUTION_CONCURRENCY = 16;
|
|
3786
3398
|
function qmdCollectionPathParts(resultPath) {
|
|
3787
|
-
if (!resultPath ||
|
|
3399
|
+
if (!resultPath || path6.isAbsolute(resultPath)) return null;
|
|
3400
|
+
if (resultPath.trim().startsWith("qmd://")) {
|
|
3401
|
+
try {
|
|
3402
|
+
const parsed = new URL(resultPath.trim());
|
|
3403
|
+
if (parsed.protocol !== "qmd:" || !parsed.hostname) return null;
|
|
3404
|
+
const collection2 = parsed.hostname;
|
|
3405
|
+
const relativePath = normalizeQmdResultPath(resultPath, collection2).replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3406
|
+
if (!relativePath) return null;
|
|
3407
|
+
return { collection: collection2, relativePath };
|
|
3408
|
+
} catch {
|
|
3409
|
+
return null;
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3788
3412
|
const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3789
3413
|
const slashIndex = normalized.indexOf("/");
|
|
3790
3414
|
if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
|
|
@@ -3797,9 +3421,9 @@ function qmdCollectionPathParts(resultPath) {
|
|
|
3797
3421
|
}
|
|
3798
3422
|
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
3799
3423
|
const candidates = /* @__PURE__ */ new Set();
|
|
3800
|
-
const storageRoot =
|
|
3424
|
+
const storageRoot = path6.resolve(storageDir);
|
|
3801
3425
|
const addCandidate = (candidate) => {
|
|
3802
|
-
const resolved =
|
|
3426
|
+
const resolved = path6.resolve(candidate);
|
|
3803
3427
|
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
3804
3428
|
candidates.add(resolved);
|
|
3805
3429
|
}
|
|
@@ -3807,18 +3431,18 @@ function qmdResultPathCandidates(storageDir, resultPath) {
|
|
|
3807
3431
|
const addRelativeCandidates = (relativePath) => {
|
|
3808
3432
|
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3809
3433
|
if (!normalized) return;
|
|
3810
|
-
addCandidate(
|
|
3434
|
+
addCandidate(path6.join(storageRoot, normalized));
|
|
3811
3435
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3812
|
-
addCandidate(
|
|
3436
|
+
addCandidate(path6.join(storageRoot, "facts", normalized));
|
|
3813
3437
|
}
|
|
3814
3438
|
};
|
|
3815
|
-
if (
|
|
3439
|
+
if (path6.isAbsolute(resultPath)) {
|
|
3816
3440
|
addCandidate(resultPath);
|
|
3817
|
-
const relative2 =
|
|
3818
|
-
if (relative2 && !relative2.startsWith("..") && !
|
|
3819
|
-
const normalized = relative2.split(
|
|
3441
|
+
const relative2 = path6.relative(storageRoot, path6.resolve(resultPath));
|
|
3442
|
+
if (relative2 && !relative2.startsWith("..") && !path6.isAbsolute(relative2)) {
|
|
3443
|
+
const normalized = relative2.split(path6.sep).join("/");
|
|
3820
3444
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3821
|
-
addCandidate(
|
|
3445
|
+
addCandidate(path6.join(storageRoot, "facts", normalized));
|
|
3822
3446
|
}
|
|
3823
3447
|
}
|
|
3824
3448
|
} else {
|
|
@@ -3848,12 +3472,13 @@ var QmdResultResolver = class {
|
|
|
3848
3472
|
const fallbackStorageDir = storageDirOrNull(fallbackStorage);
|
|
3849
3473
|
const config = this.getConfig();
|
|
3850
3474
|
const coldCollection = config.qmdColdCollection ?? "openclaw-engram-cold";
|
|
3475
|
+
const fallbackResultPath = resultPath.trim().startsWith("qmd://") && parts?.collection === config.qmdCollection ? parts.relativePath : resultPath;
|
|
3851
3476
|
if (parts && parts.collection === coldCollection) {
|
|
3852
3477
|
const storages = [];
|
|
3853
3478
|
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
3854
3479
|
const addStorage = (storage) => {
|
|
3855
3480
|
const storageDir = storageDirOrNull(storage);
|
|
3856
|
-
const storageKey = storageDir ?
|
|
3481
|
+
const storageKey = storageDir ? path6.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
3857
3482
|
if (seenStorageDirs.has(storageKey)) return;
|
|
3858
3483
|
seenStorageDirs.add(storageKey);
|
|
3859
3484
|
storages.push(storage);
|
|
@@ -3883,11 +3508,8 @@ var QmdResultResolver = class {
|
|
|
3883
3508
|
continue;
|
|
3884
3509
|
}
|
|
3885
3510
|
try {
|
|
3886
|
-
const coldRoot =
|
|
3887
|
-
for (const candidate of qmdResultPathCandidates(
|
|
3888
|
-
coldRoot,
|
|
3889
|
-
parts.relativePath
|
|
3890
|
-
)) {
|
|
3511
|
+
const coldRoot = path6.join(storageDir, "cold");
|
|
3512
|
+
for (const candidate of qmdResultPathCandidates(coldRoot, parts.relativePath)) {
|
|
3891
3513
|
const memory = await storage.readMemoryByPath(candidate);
|
|
3892
3514
|
if (memory) return memory;
|
|
3893
3515
|
}
|
|
@@ -3906,10 +3528,7 @@ var QmdResultResolver = class {
|
|
|
3906
3528
|
if (parts && collectionNamespace) {
|
|
3907
3529
|
try {
|
|
3908
3530
|
const collectionStorage = await this.storageFor(collectionNamespace);
|
|
3909
|
-
for (const candidate of qmdResultPathCandidates(
|
|
3910
|
-
collectionStorage.dir,
|
|
3911
|
-
parts.relativePath
|
|
3912
|
-
)) {
|
|
3531
|
+
for (const candidate of qmdResultPathCandidates(collectionStorage.dir, parts.relativePath)) {
|
|
3913
3532
|
const memory = await collectionStorage.readMemoryByPath(candidate);
|
|
3914
3533
|
if (memory) return memory;
|
|
3915
3534
|
}
|
|
@@ -3927,10 +3546,7 @@ var QmdResultResolver = class {
|
|
|
3927
3546
|
if (preferredNamespace) {
|
|
3928
3547
|
try {
|
|
3929
3548
|
const preferredStorage = await this.storageFor(preferredNamespace);
|
|
3930
|
-
for (const candidate of qmdResultPathCandidates(
|
|
3931
|
-
preferredStorage.dir,
|
|
3932
|
-
resultPath
|
|
3933
|
-
)) {
|
|
3549
|
+
for (const candidate of qmdResultPathCandidates(preferredStorage.dir, fallbackResultPath)) {
|
|
3934
3550
|
const memory = await preferredStorage.readMemoryByPath(candidate);
|
|
3935
3551
|
if (memory) return memory;
|
|
3936
3552
|
}
|
|
@@ -3942,54 +3558,77 @@ var QmdResultResolver = class {
|
|
|
3942
3558
|
error: err.message
|
|
3943
3559
|
});
|
|
3944
3560
|
}
|
|
3945
|
-
if (!
|
|
3561
|
+
if (!path6.isAbsolute(fallbackResultPath)) return null;
|
|
3946
3562
|
}
|
|
3947
|
-
if (
|
|
3563
|
+
if (path6.isAbsolute(fallbackResultPath)) {
|
|
3948
3564
|
if (!fallbackStorageDir) {
|
|
3949
|
-
return await fallbackStorage.readMemoryByPath(
|
|
3565
|
+
return await fallbackStorage.readMemoryByPath(fallbackResultPath);
|
|
3950
3566
|
}
|
|
3951
3567
|
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
3952
|
-
|
|
3568
|
+
fallbackResultPath,
|
|
3953
3569
|
fallbackStorage,
|
|
3954
3570
|
recallNamespaces
|
|
3955
3571
|
);
|
|
3956
3572
|
if (!ownerStorage) return null;
|
|
3957
|
-
for (const candidate of qmdResultPathCandidates(
|
|
3958
|
-
ownerStorage.dir,
|
|
3959
|
-
resultPath
|
|
3960
|
-
)) {
|
|
3573
|
+
for (const candidate of qmdResultPathCandidates(ownerStorage.dir, fallbackResultPath)) {
|
|
3961
3574
|
const memory = await ownerStorage.storage.readMemoryByPath(candidate);
|
|
3962
3575
|
if (memory) return memory;
|
|
3963
3576
|
}
|
|
3964
3577
|
return null;
|
|
3965
3578
|
}
|
|
3966
3579
|
if (!fallbackStorageDir) {
|
|
3967
|
-
return await fallbackStorage.readMemoryByPath(
|
|
3580
|
+
return await fallbackStorage.readMemoryByPath(fallbackResultPath);
|
|
3968
3581
|
}
|
|
3969
|
-
for (const candidate of qmdResultPathCandidates(
|
|
3970
|
-
fallbackStorageDir,
|
|
3971
|
-
resultPath
|
|
3972
|
-
)) {
|
|
3582
|
+
for (const candidate of qmdResultPathCandidates(fallbackStorageDir, fallbackResultPath)) {
|
|
3973
3583
|
const memory = await fallbackStorage.readMemoryByPath(candidate);
|
|
3974
3584
|
if (memory) return memory;
|
|
3975
3585
|
}
|
|
3976
3586
|
return null;
|
|
3977
3587
|
}
|
|
3588
|
+
async filterPrivateSearchResults(results, fallbackStorage, namespaces = [], preserveUnresolved = false, visibilityCache = /* @__PURE__ */ new Map()) {
|
|
3589
|
+
const namespaceKey = namespaces.join("\0");
|
|
3590
|
+
const entries = results.filter((result) => Boolean(result.path)).map((result) => ({
|
|
3591
|
+
result,
|
|
3592
|
+
cacheKey: `${namespaceKey}\0${preserveUnresolved ? "1" : "0"}\0${result.namespace ?? ""}\0${result.path}`
|
|
3593
|
+
}));
|
|
3594
|
+
const pending = /* @__PURE__ */ new Map();
|
|
3595
|
+
for (const { result, cacheKey } of entries) {
|
|
3596
|
+
if (!visibilityCache.has(cacheKey)) pending.set(cacheKey, result);
|
|
3597
|
+
}
|
|
3598
|
+
const unresolved = [...pending];
|
|
3599
|
+
for (let offset = 0; offset < unresolved.length; offset += PRIVATE_RESULT_RESOLUTION_CONCURRENCY) {
|
|
3600
|
+
await Promise.all(
|
|
3601
|
+
unresolved.slice(offset, offset + PRIVATE_RESULT_RESOLUTION_CONCURRENCY).map(async ([cacheKey, result]) => {
|
|
3602
|
+
visibilityCache.set(
|
|
3603
|
+
cacheKey,
|
|
3604
|
+
await this.isVisibleSearchResult(result, fallbackStorage, namespaces, preserveUnresolved)
|
|
3605
|
+
);
|
|
3606
|
+
})
|
|
3607
|
+
);
|
|
3608
|
+
}
|
|
3609
|
+
return entries.filter(({ cacheKey }) => visibilityCache.get(cacheKey) === true).map(({ result }) => result);
|
|
3610
|
+
}
|
|
3611
|
+
async isVisibleSearchResult(result, fallbackStorage, namespaces, preserveUnresolved) {
|
|
3612
|
+
const parts = qmdCollectionPathParts(result.path);
|
|
3613
|
+
const config = this.getConfig();
|
|
3614
|
+
const collectionIsKnownInternal = parts !== null && INTERNAL_QMD_ROOTS.has(parts.collection);
|
|
3615
|
+
const collectionIsConfigured = parts !== null && (parts.collection === config.qmdCollection || parts.collection === (config.qmdColdCollection ?? "openclaw-engram-cold") || this.qmdCollectionNamespaceFromPrefix(parts.collection) !== null);
|
|
3616
|
+
let memory = await this.readQmdResultMemory(result.path, fallbackStorage, namespaces, result.namespace);
|
|
3617
|
+
if (!memory && parts && !collectionIsKnownInternal && !collectionIsConfigured) {
|
|
3618
|
+
memory = await this.readQmdResultMemory(parts.relativePath, fallbackStorage, namespaces, result.namespace);
|
|
3619
|
+
}
|
|
3620
|
+
const absoluteInsideMemoryRoot = path6.isAbsolute(result.path) && isPathInsideStorageRoot(path6.resolve(config.memoryDir), path6.resolve(result.path));
|
|
3621
|
+
const hasExplicitQmdCollection = result.path.trim().startsWith("qmd://");
|
|
3622
|
+
const unresolvedInternalPath = !memory && (absoluteInsideMemoryRoot || collectionIsKnownInternal && (!preserveUnresolved || hasExplicitQmdCollection) || hasExplicitQmdCollection && collectionIsConfigured);
|
|
3623
|
+
const unresolvedExternalCollection = !memory && (parts !== null && !collectionIsKnownInternal && !collectionIsConfigured || path6.isAbsolute(result.path) && !isPathInsideStorageRoot(path6.resolve(config.memoryDir), path6.resolve(result.path)));
|
|
3624
|
+
return memory !== null && !isSupportPassportPrivateMemory(memory) || !memory && !unresolvedInternalPath && (preserveUnresolved || unresolvedExternalCollection);
|
|
3625
|
+
}
|
|
3978
3626
|
async resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces = []) {
|
|
3979
|
-
const memory = await this.readQmdResultMemory(
|
|
3980
|
-
result.path,
|
|
3981
|
-
fallbackStorage,
|
|
3982
|
-
recallNamespaces,
|
|
3983
|
-
result.namespace
|
|
3984
|
-
);
|
|
3627
|
+
const memory = await this.readQmdResultMemory(result.path, fallbackStorage, recallNamespaces, result.namespace);
|
|
3985
3628
|
if (!memory) return null;
|
|
3986
3629
|
let ownerNamespace = null;
|
|
3987
|
-
if (
|
|
3988
|
-
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
3989
|
-
memory.path,
|
|
3990
|
-
fallbackStorage,
|
|
3991
|
-
recallNamespaces
|
|
3992
|
-
);
|
|
3630
|
+
if (path6.isAbsolute(memory.path)) {
|
|
3631
|
+
const ownerStorage = await this.storageForAbsoluteQmdResultPath(memory.path, fallbackStorage, recallNamespaces);
|
|
3993
3632
|
ownerNamespace = ownerStorage?.namespace ?? null;
|
|
3994
3633
|
if (!ownerNamespace && resolveNamespaceCapabilities(this.getConfig()).namespaces) return null;
|
|
3995
3634
|
}
|
|
@@ -4008,17 +3647,17 @@ var QmdResultResolver = class {
|
|
|
4008
3647
|
};
|
|
4009
3648
|
}
|
|
4010
3649
|
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
4011
|
-
const resolvedPath =
|
|
3650
|
+
const resolvedPath = path6.resolve(resultPath);
|
|
4012
3651
|
const config = this.getConfig();
|
|
4013
|
-
const memoryRoot =
|
|
4014
|
-
const namespacesRoot =
|
|
3652
|
+
const memoryRoot = path6.resolve(config.memoryDir);
|
|
3653
|
+
const namespacesRoot = path6.join(memoryRoot, "namespaces");
|
|
4015
3654
|
const fallbackStorageDir = storageDirOrNull(fallbackStorage);
|
|
4016
3655
|
const matches = [];
|
|
4017
3656
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
4018
3657
|
const maybeAddStorage = (storage, namespace) => {
|
|
4019
3658
|
const storageDir = storageDirOrNull(storage);
|
|
4020
3659
|
if (!storageDir) return;
|
|
4021
|
-
const candidateRoot =
|
|
3660
|
+
const candidateRoot = path6.resolve(storageDir);
|
|
4022
3661
|
if (seenDirs.has(candidateRoot)) return;
|
|
4023
3662
|
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
4024
3663
|
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
@@ -4036,12 +3675,10 @@ var QmdResultResolver = class {
|
|
|
4036
3675
|
candidateNamespaces.add(ns);
|
|
4037
3676
|
}
|
|
4038
3677
|
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
4039
|
-
const relativeToNamespaces =
|
|
3678
|
+
const relativeToNamespaces = path6.relative(namespacesRoot, resolvedPath);
|
|
4040
3679
|
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
4041
3680
|
if (namespaceSegment) {
|
|
4042
|
-
candidateNamespaces.add(
|
|
4043
|
-
namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment
|
|
4044
|
-
);
|
|
3681
|
+
candidateNamespaces.add(namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment);
|
|
4045
3682
|
}
|
|
4046
3683
|
}
|
|
4047
3684
|
for (const policy of config.namespacePolicies ?? []) {
|
|
@@ -4052,7 +3689,6 @@ var QmdResultResolver = class {
|
|
|
4052
3689
|
try {
|
|
4053
3690
|
maybeAddStorage(await this.storageFor(ns), ns);
|
|
4054
3691
|
} catch {
|
|
4055
|
-
continue;
|
|
4056
3692
|
}
|
|
4057
3693
|
}
|
|
4058
3694
|
matches.sort((a, b) => b.dir.length - a.dir.length);
|
|
@@ -4580,7 +4216,7 @@ function collectSpeakers(tagged) {
|
|
|
4580
4216
|
}
|
|
4581
4217
|
|
|
4582
4218
|
// src/wearables/fusion/fuse.ts
|
|
4583
|
-
import { createHash as
|
|
4219
|
+
import { createHash as createHash2 } from "crypto";
|
|
4584
4220
|
var FUSION_ID_PREFIX = "fusion";
|
|
4585
4221
|
var FUSION_ALGO_VERSION = "2026-07-12-1";
|
|
4586
4222
|
function canonicalInputsKey(date, inputs) {
|
|
@@ -4609,7 +4245,7 @@ function canonicalInputsKey(date, inputs) {
|
|
|
4609
4245
|
])
|
|
4610
4246
|
])
|
|
4611
4247
|
];
|
|
4612
|
-
return
|
|
4248
|
+
return createHash2("sha256").update(JSON.stringify(record), "utf-8").digest("hex");
|
|
4613
4249
|
}
|
|
4614
4250
|
function configFingerprint(options, sources) {
|
|
4615
4251
|
const proximityGapMs = options.proximityGapMs ?? DEFAULT_PROXIMITY_GAP_MS;
|
|
@@ -4624,7 +4260,7 @@ function canonicalDayKey(date, inputs, options, algoVersion = FUSION_ALGO_VERSIO
|
|
|
4624
4260
|
options,
|
|
4625
4261
|
inputs.map((conv) => conv.source)
|
|
4626
4262
|
);
|
|
4627
|
-
return
|
|
4263
|
+
return createHash2("sha256").update(inputsKey).update("\n").update(fingerprint).update("\n").update(algoVersion).digest("hex");
|
|
4628
4264
|
}
|
|
4629
4265
|
function buildProvenance(cluster, proximityGapMs, windowToleranceMs) {
|
|
4630
4266
|
return {
|
|
@@ -4684,11 +4320,11 @@ function fuseDay(date, inputs, options = {}) {
|
|
|
4684
4320
|
}
|
|
4685
4321
|
|
|
4686
4322
|
// src/wearables/fusion/store.ts
|
|
4687
|
-
import { createHash as
|
|
4688
|
-
import * as
|
|
4323
|
+
import { createHash as createHash3 } from "crypto";
|
|
4324
|
+
import * as path7 from "path";
|
|
4689
4325
|
var FUSION_KIND = "wearable-fusion";
|
|
4690
4326
|
function hashFusionBody(conversations) {
|
|
4691
|
-
return
|
|
4327
|
+
return createHash3("sha256").update(JSON.stringify(conversations), "utf-8").digest("hex");
|
|
4692
4328
|
}
|
|
4693
4329
|
function composeFusionDayMeta(date, conversations, sources, contentHash, fusedAt) {
|
|
4694
4330
|
return {
|
|
@@ -4872,7 +4508,7 @@ var FusionArtifactStore = class {
|
|
|
4872
4508
|
`invalid wearable fusion date '${String(date)}' \u2014 expected YYYY-MM-DD`
|
|
4873
4509
|
);
|
|
4874
4510
|
}
|
|
4875
|
-
return
|
|
4511
|
+
return path7.join(this.wearablesDir, FUSION_DIR_NAME, `${date}.md`);
|
|
4876
4512
|
}
|
|
4877
4513
|
async writeFusedDay(date, serialized) {
|
|
4878
4514
|
const filePath = this.fusedDayPath(date);
|
|
@@ -4909,7 +4545,7 @@ var FusionArtifactStore = class {
|
|
|
4909
4545
|
}
|
|
4910
4546
|
/** List dates with stored fused artifacts, newest first. */
|
|
4911
4547
|
async listFusedDays() {
|
|
4912
|
-
const fusionDir =
|
|
4548
|
+
const fusionDir = path7.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4913
4549
|
await this.assertPathContained(fusionDir);
|
|
4914
4550
|
let entries;
|
|
4915
4551
|
try {
|
|
@@ -4953,10 +4589,10 @@ var FusionArtifactStore = class {
|
|
|
4953
4589
|
try {
|
|
4954
4590
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
4955
4591
|
} catch {
|
|
4956
|
-
rootReal =
|
|
4592
|
+
rootReal = path7.resolve(this.memoryDir);
|
|
4957
4593
|
}
|
|
4958
4594
|
await this.assertNoEscape(rootReal, this.wearablesDir);
|
|
4959
|
-
await this.assertNoEscape(rootReal,
|
|
4595
|
+
await this.assertNoEscape(rootReal, path7.dirname(targetPath));
|
|
4960
4596
|
await this.assertNoEscape(rootReal, targetPath);
|
|
4961
4597
|
await this.assertFusionDirNotSymlinked();
|
|
4962
4598
|
}
|
|
@@ -4970,7 +4606,7 @@ var FusionArtifactStore = class {
|
|
|
4970
4606
|
* (a fresh write creates a real directory lexically under the root).
|
|
4971
4607
|
*/
|
|
4972
4608
|
async assertFusionDirNotSymlinked() {
|
|
4973
|
-
const fusionDir =
|
|
4609
|
+
const fusionDir = path7.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4974
4610
|
let stat3;
|
|
4975
4611
|
try {
|
|
4976
4612
|
stat3 = await this.io.lstat(fusionDir);
|
|
@@ -5105,8 +4741,8 @@ function reconstructFusionInputs(date, dayTranscripts) {
|
|
|
5105
4741
|
}
|
|
5106
4742
|
|
|
5107
4743
|
// src/meetings/store.ts
|
|
5108
|
-
import { createHash as
|
|
5109
|
-
import * as
|
|
4744
|
+
import { createHash as createHash4 } from "crypto";
|
|
4745
|
+
import * as path8 from "path";
|
|
5110
4746
|
var MEETINGS_DIR_NAME = "meetings";
|
|
5111
4747
|
var MEETING_KIND = "meeting";
|
|
5112
4748
|
var MEETING_FORMAT_VERSION = 1;
|
|
@@ -5136,7 +4772,7 @@ function canonicalContent(base, fused) {
|
|
|
5136
4772
|
});
|
|
5137
4773
|
}
|
|
5138
4774
|
function composeMeetingRecord(base, fused) {
|
|
5139
|
-
const contentHash =
|
|
4775
|
+
const contentHash = createHash4("sha256").update(canonicalContent(base, fused), "utf-8").digest("hex");
|
|
5140
4776
|
return {
|
|
5141
4777
|
...base,
|
|
5142
4778
|
...fused,
|
|
@@ -5275,7 +4911,7 @@ var MeetingRecordStore = class {
|
|
|
5275
4911
|
constructor(memoryDir, io) {
|
|
5276
4912
|
this.memoryDir = memoryDir;
|
|
5277
4913
|
this.io = io;
|
|
5278
|
-
this.meetingsDir =
|
|
4914
|
+
this.meetingsDir = path8.join(memoryDir, MEETINGS_DIR_NAME);
|
|
5279
4915
|
}
|
|
5280
4916
|
memoryDir;
|
|
5281
4917
|
io;
|
|
@@ -5291,7 +4927,7 @@ var MeetingRecordStore = class {
|
|
|
5291
4927
|
if (idDate !== date) {
|
|
5292
4928
|
throw new Error(`meeting id '${id}' does not belong to date '${date}'`);
|
|
5293
4929
|
}
|
|
5294
|
-
return
|
|
4930
|
+
return path8.join(this.meetingsDir, date, `${id}.md`);
|
|
5295
4931
|
}
|
|
5296
4932
|
/** Idempotently persist a record: skip the write when contentHash is unchanged. */
|
|
5297
4933
|
async saveMeetingRecord(record) {
|
|
@@ -5322,7 +4958,7 @@ var MeetingRecordStore = class {
|
|
|
5322
4958
|
if (!isValidTranscriptDate(date)) {
|
|
5323
4959
|
throw new Error(`invalid meeting date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
5324
4960
|
}
|
|
5325
|
-
const dayDir =
|
|
4961
|
+
const dayDir = path8.join(this.meetingsDir, date);
|
|
5326
4962
|
await this.assertPathContained(dayDir);
|
|
5327
4963
|
let entries;
|
|
5328
4964
|
try {
|
|
@@ -5390,10 +5026,10 @@ var MeetingRecordStore = class {
|
|
|
5390
5026
|
try {
|
|
5391
5027
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
5392
5028
|
} catch {
|
|
5393
|
-
rootReal =
|
|
5029
|
+
rootReal = path8.resolve(this.memoryDir);
|
|
5394
5030
|
}
|
|
5395
5031
|
await this.assertNoEscape(rootReal, this.meetingsDir);
|
|
5396
|
-
await this.assertNoEscape(rootReal,
|
|
5032
|
+
await this.assertNoEscape(rootReal, path8.dirname(targetPath));
|
|
5397
5033
|
await this.assertNoEscape(rootReal, targetPath);
|
|
5398
5034
|
await this.assertNotSymlink(this.meetingsDir, "directory");
|
|
5399
5035
|
const dayDir = this.dayDirWithin(targetPath);
|
|
@@ -5403,11 +5039,11 @@ var MeetingRecordStore = class {
|
|
|
5403
5039
|
/** The `<meetings>/<date>` directory on the path to `targetPath`, or null when
|
|
5404
5040
|
* `targetPath` is the meetings root itself. */
|
|
5405
5041
|
dayDirWithin(targetPath) {
|
|
5406
|
-
const rel =
|
|
5407
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
5408
|
-
const first = rel.split(
|
|
5042
|
+
const rel = path8.relative(this.meetingsDir, targetPath);
|
|
5043
|
+
if (rel === "" || rel.startsWith("..") || path8.isAbsolute(rel)) return null;
|
|
5044
|
+
const first = rel.split(path8.sep)[0];
|
|
5409
5045
|
if (first === void 0 || first.length === 0) return null;
|
|
5410
|
-
return
|
|
5046
|
+
return path8.join(this.meetingsDir, first);
|
|
5411
5047
|
}
|
|
5412
5048
|
async assertNotSymlink(target, kind) {
|
|
5413
5049
|
let stat3;
|
|
@@ -5418,7 +5054,7 @@ var MeetingRecordStore = class {
|
|
|
5418
5054
|
throw err;
|
|
5419
5055
|
}
|
|
5420
5056
|
if (stat3.isSymbolicLink) {
|
|
5421
|
-
const label =
|
|
5057
|
+
const label = path8.relative(this.memoryDir, target) || MEETINGS_DIR_NAME;
|
|
5422
5058
|
throw new Error(
|
|
5423
5059
|
`meetings ${kind} '${label}' is a symbolic link \u2014 refusing to follow it even when it resolves inside the memory dir (AGENTS.md pattern #3)`
|
|
5424
5060
|
);
|
|
@@ -5442,8 +5078,8 @@ var SORT_STR = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
|
5442
5078
|
|
|
5443
5079
|
// src/storage/supersession-audit.ts
|
|
5444
5080
|
import { readdir as readdir5 } from "fs/promises";
|
|
5445
|
-
import
|
|
5446
|
-
async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody) {
|
|
5081
|
+
import path9 from "path";
|
|
5082
|
+
async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody, structuredAttributes) {
|
|
5447
5083
|
let entries;
|
|
5448
5084
|
try {
|
|
5449
5085
|
entries = await readdir5(lookup.correctionsDir, { withFileTypes: true });
|
|
@@ -5453,8 +5089,10 @@ async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody)
|
|
|
5453
5089
|
}
|
|
5454
5090
|
for (const entry of entries) {
|
|
5455
5091
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
5456
|
-
const memory = await lookup.readMemoryByPath(
|
|
5457
|
-
if (memory?.frontmatter.category === "correction" && (memory.frontmatter.sourceMemoryId === oldMemoryId || memory.frontmatter.sourceMemoryId === void 0 && memory.frontmatter.lineage?.includes(oldMemoryId)) && memory.frontmatter.lineage?.includes(newMemoryId) && memory.content === auditBody)
|
|
5092
|
+
const memory = await lookup.readMemoryByPath(path9.join(lookup.correctionsDir, entry.name));
|
|
5093
|
+
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(
|
|
5094
|
+
([key, value]) => memory.frontmatter.structuredAttributes?.[key] === value
|
|
5095
|
+
))) {
|
|
5458
5096
|
return true;
|
|
5459
5097
|
}
|
|
5460
5098
|
}
|
|
@@ -5502,7 +5140,7 @@ async function runSupersessionSideEffects(options) {
|
|
|
5502
5140
|
if (!exists) await options.appendTombstone(exactInput);
|
|
5503
5141
|
}
|
|
5504
5142
|
}
|
|
5505
|
-
const auditBody = `Superseded: ${currentBefore.content}
|
|
5143
|
+
const auditBody = `Superseded: ${options.audit?.content ?? currentBefore.content}
|
|
5506
5144
|
|
|
5507
5145
|
Reason: ${reason}`;
|
|
5508
5146
|
const auditExists = await hasSupersessionAudit(
|
|
@@ -5512,7 +5150,8 @@ Reason: ${reason}`;
|
|
|
5512
5150
|
},
|
|
5513
5151
|
oldMemoryId,
|
|
5514
5152
|
newMemoryId,
|
|
5515
|
-
auditBody
|
|
5153
|
+
auditBody,
|
|
5154
|
+
options.audit?.structuredAttributes
|
|
5516
5155
|
);
|
|
5517
5156
|
if (!auditExists) {
|
|
5518
5157
|
const auditEnvelope = composeMemoryEnvelope(
|
|
@@ -5520,11 +5159,13 @@ Reason: ${reason}`;
|
|
|
5520
5159
|
content: auditBody,
|
|
5521
5160
|
category: "correction",
|
|
5522
5161
|
confidence: 1,
|
|
5523
|
-
tags: ["supersession", "auto-resolved"]
|
|
5162
|
+
tags: options.audit?.tags ?? ["supersession", "auto-resolved"],
|
|
5163
|
+
structuredAttributes: options.audit?.structuredAttributes
|
|
5524
5164
|
},
|
|
5525
|
-
{ source: "contradiction-detection" }
|
|
5165
|
+
{ source: options.audit?.source ?? "contradiction-detection" }
|
|
5526
5166
|
);
|
|
5527
5167
|
await options.writeSealedMemory(auditEnvelope, {
|
|
5168
|
+
actor: options.actor,
|
|
5528
5169
|
lineage: [oldMemoryId, newMemoryId],
|
|
5529
5170
|
sourceMemoryId: oldMemoryId
|
|
5530
5171
|
});
|
|
@@ -5538,7 +5179,7 @@ Reason: ${reason}`;
|
|
|
5538
5179
|
}
|
|
5539
5180
|
|
|
5540
5181
|
// src/storage/entity-timeline.ts
|
|
5541
|
-
import { createHash as
|
|
5182
|
+
import { createHash as createHash5 } from "crypto";
|
|
5542
5183
|
function parseEntityTimelineBullet(bullet, fallbackTimestamp) {
|
|
5543
5184
|
const trimmed = bullet.trim();
|
|
5544
5185
|
if (!trimmed) return null;
|
|
@@ -5910,7 +5551,7 @@ function fingerprintEntityStructuredFacts(entity) {
|
|
|
5910
5551
|
(left, right) => left.key.localeCompare(right.key) || left.title.localeCompare(right.title) || left.facts.join("\n").localeCompare(right.facts.join("\n"))
|
|
5911
5552
|
);
|
|
5912
5553
|
if (normalizedSections.length === 0) return void 0;
|
|
5913
|
-
return
|
|
5554
|
+
return createHash5("sha256").update(JSON.stringify(normalizedSections)).digest("hex");
|
|
5914
5555
|
}
|
|
5915
5556
|
function isEntitySynthesisStale(entity) {
|
|
5916
5557
|
const structuredFactCount = countEntityStructuredFacts(entity);
|
|
@@ -6457,17 +6098,17 @@ function inferEntityTypeFromContent(content) {
|
|
|
6457
6098
|
}
|
|
6458
6099
|
var KNOWN_ENTITY_FILENAME_PREFIXES = /* @__PURE__ */ new Set(["company", "other", "person", "place", "project", "tool", "topic"]);
|
|
6459
6100
|
function inferEntityTypeFromFilename(pathRel) {
|
|
6460
|
-
const basename =
|
|
6101
|
+
const basename = path10.basename(pathRel, ".md").toLowerCase();
|
|
6461
6102
|
const separator = basename.indexOf("-");
|
|
6462
6103
|
if (separator <= 0) return void 0;
|
|
6463
6104
|
const candidate = basename.slice(0, separator);
|
|
6464
6105
|
return KNOWN_ENTITY_FILENAME_PREFIXES.has(candidate) ? candidate : void 0;
|
|
6465
6106
|
}
|
|
6466
6107
|
function normalizeFrontmatterForPath(frontmatter, pathRel, content = "") {
|
|
6467
|
-
const normalizedPath = pathRel.split(
|
|
6108
|
+
const normalizedPath = pathRel.split(path10.sep).join("/");
|
|
6468
6109
|
let normalizedFrontmatter = frontmatter;
|
|
6469
6110
|
if (normalizedPath === "entities" || normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/")) {
|
|
6470
|
-
const basename =
|
|
6111
|
+
const basename = path10.basename(pathRel, ".md");
|
|
6471
6112
|
const inferredType = inferEntityTypeFromContent(content) || inferEntityTypeFromFilename(pathRel) || "entity";
|
|
6472
6113
|
const existingTags = Array.isArray(frontmatter.tags) ? frontmatter.tags : [];
|
|
6473
6114
|
normalizedFrontmatter = {
|
|
@@ -6934,9 +6575,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6934
6575
|
this.entitySchemas = entitySchemas;
|
|
6935
6576
|
this.deletionRevisionStore = new DeletionRevisionStore({
|
|
6936
6577
|
baseDir,
|
|
6937
|
-
deletionRevisionMetadataPath:
|
|
6938
|
-
invalidationCommitMetadataPath:
|
|
6939
|
-
deletionRevisionLockPath:
|
|
6578
|
+
deletionRevisionMetadataPath: path10.join(baseDir, ".offline-sync", "deletion-revisions.v1.json"),
|
|
6579
|
+
invalidationCommitMetadataPath: path10.join(baseDir, ".offline-sync", "invalidation-commits.v1.json"),
|
|
6580
|
+
deletionRevisionLockPath: path10.join(baseDir, ".offline-sync", "deletion-revisions.v1.json.lock"),
|
|
6940
6581
|
assertManagedStoragePath: (filePath, method) => this.assertManagedStoragePath(filePath, method)
|
|
6941
6582
|
});
|
|
6942
6583
|
this.hotMemoriesCacheEnabled = hotMemoriesCacheEnabledOverride ?? _StorageManager.hotMemoriesCacheDefaultByDir.get(baseDir) ?? _StorageManager.hotMemoriesCacheDefault;
|
|
@@ -7124,8 +6765,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7124
6765
|
}
|
|
7125
6766
|
/** Whether `filePath` resolves to `stateDir` itself or a path contained in it. */
|
|
7126
6767
|
isStateFilePath(filePath) {
|
|
7127
|
-
const rel =
|
|
7128
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
6768
|
+
const rel = path10.relative(this.stateDir, path10.resolve(filePath));
|
|
6769
|
+
return rel === "" || !rel.startsWith("..") && !path10.isAbsolute(rel);
|
|
7129
6770
|
}
|
|
7130
6771
|
// ── Tombstone store (issue #1579) ───────────────────────────────────────
|
|
7131
6772
|
// Instance-scoped (rule 11) + namespace-scoped (rule 42) tombstone index.
|
|
@@ -7240,8 +6881,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7240
6881
|
* /srv/cold/remnic), skipping the patch and stranding a stale hot entry.
|
|
7241
6882
|
*/
|
|
7242
6883
|
isColdOrArchiveTierPath(p) {
|
|
7243
|
-
const rel =
|
|
7244
|
-
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${
|
|
6884
|
+
const rel = path10.relative(this.baseDir, p);
|
|
6885
|
+
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${path10.sep}`) || rel.startsWith(`archive${path10.sep}`);
|
|
7245
6886
|
}
|
|
7246
6887
|
/**
|
|
7247
6888
|
* Mark the secure-store as required for this storage instance.
|
|
@@ -7328,7 +6969,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7328
6969
|
void 0,
|
|
7329
6970
|
this.baseDir
|
|
7330
6971
|
);
|
|
7331
|
-
const rel =
|
|
6972
|
+
const rel = path10.relative(this.baseDir, filePath).split(path10.sep).join("/");
|
|
7332
6973
|
return `${rel}:${version.versionId}`;
|
|
7333
6974
|
} catch (err) {
|
|
7334
6975
|
log.warn(
|
|
@@ -7408,12 +7049,12 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7408
7049
|
}
|
|
7409
7050
|
identityFilePath(workspaceDir, namespace) {
|
|
7410
7051
|
const rawNamespace = typeof namespace === "string" ? namespace.trim() : "";
|
|
7411
|
-
if (!rawNamespace) return
|
|
7052
|
+
if (!rawNamespace) return path10.join(workspaceDir, "IDENTITY.md");
|
|
7412
7053
|
const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
7413
|
-
return
|
|
7054
|
+
return path10.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);
|
|
7414
7055
|
}
|
|
7415
7056
|
versionFilePath(kind) {
|
|
7416
|
-
return
|
|
7057
|
+
return path10.join(this.stateDir, `.${kind}-version.log`);
|
|
7417
7058
|
}
|
|
7418
7059
|
bumpSharedVersion(kind, fallbackMap) {
|
|
7419
7060
|
const filePath = this.versionFilePath(kind);
|
|
@@ -7517,7 +7158,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7517
7158
|
// memories.
|
|
7518
7159
|
// -------------------------------------------------------------------------
|
|
7519
7160
|
get wearablesDir() {
|
|
7520
|
-
return
|
|
7161
|
+
return path10.join(this.baseDir, WEARABLES_DIR_NAME);
|
|
7521
7162
|
}
|
|
7522
7163
|
/**
|
|
7523
7164
|
* Resolve the on-disk path for a source/day transcript. Throws on
|
|
@@ -7533,7 +7174,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7533
7174
|
if (!isValidTranscriptDate(date)) {
|
|
7534
7175
|
throw new Error(`invalid wearable transcript date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
7535
7176
|
}
|
|
7536
|
-
return
|
|
7177
|
+
return path10.join(this.wearablesDir, sourceId, `${date}.md`);
|
|
7537
7178
|
}
|
|
7538
7179
|
async writeWearableDayTranscript(sourceId, date, serialized) {
|
|
7539
7180
|
const targetPath = this.wearableTranscriptPath(sourceId, date);
|
|
@@ -7560,9 +7201,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7560
7201
|
writeFile: (p, c) => this.writeStorageSecureFile(p, c),
|
|
7561
7202
|
readFile: (p) => readMaybeEncryptedFile(p, this._secureStoreKey, this.baseDir),
|
|
7562
7203
|
readDir: (d) => readdir6(d),
|
|
7563
|
-
deleteFile: (p) =>
|
|
7204
|
+
deleteFile: (p) => unlink4(p),
|
|
7564
7205
|
realpath: (p) => realpath3(p),
|
|
7565
|
-
lstat: (p) =>
|
|
7206
|
+
lstat: (p) => lstat3(p).then((st) => ({ isSymbolicLink: st.isSymbolicLink() }))
|
|
7566
7207
|
});
|
|
7567
7208
|
}
|
|
7568
7209
|
_meetingRecordStore;
|
|
@@ -7578,9 +7219,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7578
7219
|
writeFile: (p, c) => this.writeStorageSecureFile(p, c),
|
|
7579
7220
|
readFile: (p) => readMaybeEncryptedFile(p, this._secureStoreKey, this.baseDir),
|
|
7580
7221
|
readDir: (d) => readdir6(d),
|
|
7581
|
-
deleteFile: (p) =>
|
|
7222
|
+
deleteFile: (p) => unlink4(p),
|
|
7582
7223
|
realpath: (p) => realpath3(p),
|
|
7583
|
-
lstat: (p) =>
|
|
7224
|
+
lstat: (p) => lstat3(p).then((st) => ({ isSymbolicLink: st.isSymbolicLink() }))
|
|
7584
7225
|
});
|
|
7585
7226
|
}
|
|
7586
7227
|
/**
|
|
@@ -7649,25 +7290,25 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7649
7290
|
});
|
|
7650
7291
|
}
|
|
7651
7292
|
get factsDir() {
|
|
7652
|
-
return
|
|
7293
|
+
return path10.join(this.baseDir, "facts");
|
|
7653
7294
|
}
|
|
7654
7295
|
get correctionsDir() {
|
|
7655
|
-
return
|
|
7296
|
+
return path10.join(this.baseDir, "corrections");
|
|
7656
7297
|
}
|
|
7657
7298
|
get proceduresDir() {
|
|
7658
|
-
return
|
|
7299
|
+
return path10.join(this.baseDir, "procedures");
|
|
7659
7300
|
}
|
|
7660
7301
|
get reasoningTracesDir() {
|
|
7661
|
-
return
|
|
7302
|
+
return path10.join(this.baseDir, "reasoning-traces");
|
|
7662
7303
|
}
|
|
7663
7304
|
get entitiesDir() {
|
|
7664
|
-
return
|
|
7305
|
+
return path10.join(this.baseDir, "entities");
|
|
7665
7306
|
}
|
|
7666
7307
|
resolveEntityFilePath(name) {
|
|
7667
7308
|
if (typeof name !== "string") return null;
|
|
7668
|
-
const filePath =
|
|
7669
|
-
const relative2 =
|
|
7670
|
-
if (relative2 === "" || relative2.startsWith("..") ||
|
|
7309
|
+
const filePath = path10.resolve(this.entitiesDir, `${name}.md`);
|
|
7310
|
+
const relative2 = path10.relative(this.entitiesDir, filePath);
|
|
7311
|
+
if (relative2 === "" || relative2.startsWith("..") || path10.isAbsolute(relative2)) {
|
|
7671
7312
|
return null;
|
|
7672
7313
|
}
|
|
7673
7314
|
return filePath;
|
|
@@ -7678,7 +7319,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7678
7319
|
async readDependencyPropagationQueueFile(filePath) {
|
|
7679
7320
|
const target = await resolveSafeStoragePath(
|
|
7680
7321
|
this.baseDir,
|
|
7681
|
-
|
|
7322
|
+
path10.relative(
|
|
7682
7323
|
this.baseDir,
|
|
7683
7324
|
this.assertManagedStoragePath(filePath, "storage.readDependencyPropagationQueueFile")
|
|
7684
7325
|
)
|
|
@@ -7688,7 +7329,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7688
7329
|
async writeDependencyPropagationQueueFile(filePath, content) {
|
|
7689
7330
|
const target = await resolveSafeStoragePath(
|
|
7690
7331
|
this.baseDir,
|
|
7691
|
-
|
|
7332
|
+
path10.relative(
|
|
7692
7333
|
this.baseDir,
|
|
7693
7334
|
this.assertManagedStoragePath(filePath, "storage.writeDependencyPropagationQueueFile")
|
|
7694
7335
|
)
|
|
@@ -7702,10 +7343,10 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7702
7343
|
});
|
|
7703
7344
|
}
|
|
7704
7345
|
assertManagedStoragePath(filePath, method) {
|
|
7705
|
-
const resolved =
|
|
7706
|
-
const base =
|
|
7707
|
-
const rel =
|
|
7708
|
-
if (rel === "" || rel === ".." || rel.startsWith(`..${
|
|
7346
|
+
const resolved = path10.resolve(filePath);
|
|
7347
|
+
const base = path10.resolve(this.baseDir);
|
|
7348
|
+
const rel = path10.relative(base, resolved);
|
|
7349
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${path10.sep}`) || path10.isAbsolute(rel)) {
|
|
7709
7350
|
throw new Error(`${method}: file path escapes memory dir`);
|
|
7710
7351
|
}
|
|
7711
7352
|
return resolved;
|
|
@@ -7738,7 +7379,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7738
7379
|
async digestOfflineSyncFile(filePath) {
|
|
7739
7380
|
const target = this.assertManagedStoragePath(filePath, "storage.digestOfflineSyncFile");
|
|
7740
7381
|
const st = await stat2(target);
|
|
7741
|
-
const relPath =
|
|
7382
|
+
const relPath = path10.relative(this.baseDir, target).split(path10.sep).join("/");
|
|
7742
7383
|
const cache = await this.loadOfflineSyncDigestCache();
|
|
7743
7384
|
const cached = cache.get(relPath);
|
|
7744
7385
|
if (cached && cached.statBytes === st.size && cached.mtimeMs === st.mtimeMs && cached.ctimeMs === st.ctimeMs && !cached.encrypted) {
|
|
@@ -7752,11 +7393,11 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7752
7393
|
if (encrypted) {
|
|
7753
7394
|
const content = await readMaybeEncryptedFileBuffer(target, this._secureStoreKey, this.baseDir);
|
|
7754
7395
|
digest = {
|
|
7755
|
-
sha256:
|
|
7396
|
+
sha256: createHash6("sha256").update(content).digest("hex"),
|
|
7756
7397
|
bytes: content.byteLength
|
|
7757
7398
|
};
|
|
7758
7399
|
} else {
|
|
7759
|
-
const hash =
|
|
7400
|
+
const hash = createHash6("sha256");
|
|
7760
7401
|
let bytes = 0;
|
|
7761
7402
|
for await (const rawChunk of createReadStream(target)) {
|
|
7762
7403
|
const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);
|
|
@@ -7784,7 +7425,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7784
7425
|
async readOfflineSyncDigestCache() {
|
|
7785
7426
|
const cache = /* @__PURE__ */ new Map();
|
|
7786
7427
|
try {
|
|
7787
|
-
const raw = await
|
|
7428
|
+
const raw = await readFile2(this.offlineSyncDigestCachePath, "utf-8");
|
|
7788
7429
|
const parsed = JSON.parse(raw);
|
|
7789
7430
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return cache;
|
|
7790
7431
|
const entries = parsed.entries;
|
|
@@ -7799,7 +7440,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7799
7440
|
const bytes = typeof record.bytes === "number" ? record.bytes : NaN;
|
|
7800
7441
|
const sha256 = typeof record.sha256 === "string" ? record.sha256 : "";
|
|
7801
7442
|
const encrypted = record.encrypted === true;
|
|
7802
|
-
if (cachePath.length === 0 || cachePath === ".." || cachePath.startsWith("../") ||
|
|
7443
|
+
if (cachePath.length === 0 || cachePath === ".." || cachePath.startsWith("../") || path10.isAbsolute(cachePath) || !Number.isFinite(statBytes) || !Number.isFinite(mtimeMs) || !Number.isFinite(ctimeMs) || !Number.isFinite(bytes) || !/^[a-f0-9]{64}$/i.test(sha256)) {
|
|
7803
7444
|
continue;
|
|
7804
7445
|
}
|
|
7805
7446
|
cache.set(cachePath, { statBytes, mtimeMs, ctimeMs, encrypted, sha256, bytes });
|
|
@@ -7841,7 +7482,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7841
7482
|
const cache = this.offlineSyncDigestCache;
|
|
7842
7483
|
if (!cache) return;
|
|
7843
7484
|
const entries = [...cache.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([entryPath, entry]) => ({ path: entryPath, ...entry }));
|
|
7844
|
-
await
|
|
7485
|
+
await mkdir(path10.dirname(this.offlineSyncDigestCachePath), { recursive: true });
|
|
7845
7486
|
await writeFile2(this.offlineSyncDigestCachePath, `${JSON.stringify({ version: 1, entries })}
|
|
7846
7487
|
`, "utf-8");
|
|
7847
7488
|
}).catch((err) => {
|
|
@@ -7851,7 +7492,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7851
7492
|
});
|
|
7852
7493
|
}
|
|
7853
7494
|
async offlineSyncFileIsEncrypted(filePath) {
|
|
7854
|
-
const handle = await
|
|
7495
|
+
const handle = await open(filePath, "r");
|
|
7855
7496
|
try {
|
|
7856
7497
|
const header = Buffer.alloc(MAGIC_HEADER_SIZE);
|
|
7857
7498
|
const { bytesRead } = await handle.read(header, 0, header.length, 0);
|
|
@@ -7910,7 +7551,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7910
7551
|
}
|
|
7911
7552
|
let handle;
|
|
7912
7553
|
try {
|
|
7913
|
-
handle = await
|
|
7554
|
+
handle = await open(filePath, "r");
|
|
7914
7555
|
} catch (err) {
|
|
7915
7556
|
if (isErrnoCode(err, "ENOENT")) return false;
|
|
7916
7557
|
throw err;
|
|
@@ -7930,7 +7571,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7930
7571
|
}
|
|
7931
7572
|
async appendStorageSecureFileUnlocked(filePath, content) {
|
|
7932
7573
|
const writeKey = this.resolveWriteKey();
|
|
7933
|
-
await
|
|
7574
|
+
await mkdir(path10.dirname(filePath), { recursive: true });
|
|
7934
7575
|
if (writeKey === null) {
|
|
7935
7576
|
try {
|
|
7936
7577
|
if (await this.isEncryptedFileHeader(filePath)) {
|
|
@@ -7956,13 +7597,13 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7956
7597
|
this.notifyCatalogWriteForPath(filePath);
|
|
7957
7598
|
}
|
|
7958
7599
|
get stateDir() {
|
|
7959
|
-
return
|
|
7600
|
+
return path10.join(this.baseDir, "state");
|
|
7960
7601
|
}
|
|
7961
7602
|
get offlineSyncDigestCachePath() {
|
|
7962
|
-
return
|
|
7603
|
+
return path10.join(this.baseDir, ".offline-sync", "digest-cache.v1.json");
|
|
7963
7604
|
}
|
|
7964
7605
|
get entitySynthesisQueuePath() {
|
|
7965
|
-
return
|
|
7606
|
+
return path10.join(this.stateDir, "entity-synthesis-queue.json");
|
|
7966
7607
|
}
|
|
7967
7608
|
// ── Tombstone store access (issue #1579) ─────────────────────────────────
|
|
7968
7609
|
/**
|
|
@@ -7972,7 +7613,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7972
7613
|
* helpers are injected into the store).
|
|
7973
7614
|
*/
|
|
7974
7615
|
get tombstonesPath() {
|
|
7975
|
-
return
|
|
7616
|
+
return path10.join(this.stateDir, "tombstones.jsonl");
|
|
7976
7617
|
}
|
|
7977
7618
|
/**
|
|
7978
7619
|
* Configure the tombstone invariant for this storage instance. Installed
|
|
@@ -8002,7 +7643,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8002
7643
|
const requested = new Set(sourceMemoryIds);
|
|
8003
7644
|
const sourcePaths = await (sourcePathsPromise ??= this.memoryReadStore.collectTombstoneMigrationPaths());
|
|
8004
7645
|
const directPaths = sourcePaths.filter(
|
|
8005
|
-
(filePath) => requested.has(
|
|
7646
|
+
(filePath) => requested.has(path10.basename(filePath, ".md"))
|
|
8006
7647
|
);
|
|
8007
7648
|
const contents = /* @__PURE__ */ new Map();
|
|
8008
7649
|
for (const memory of await this.readParsedMemoriesFromPaths(directPaths, 50)) {
|
|
@@ -8296,55 +7937,55 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8296
7937
|
return legacyMatches.length > 0 ? [...new Set(legacyMatches.map((content) => ContentHashIndex.computeHash(content)))] : [persistedHash];
|
|
8297
7938
|
}
|
|
8298
7939
|
get questionsDir() {
|
|
8299
|
-
return
|
|
7940
|
+
return path10.join(this.baseDir, "questions");
|
|
8300
7941
|
}
|
|
8301
7942
|
get artifactsDir() {
|
|
8302
|
-
return
|
|
7943
|
+
return path10.join(this.baseDir, "artifacts");
|
|
8303
7944
|
}
|
|
8304
7945
|
get identityDir() {
|
|
8305
|
-
return
|
|
7946
|
+
return path10.join(this.baseDir, "identity");
|
|
8306
7947
|
}
|
|
8307
7948
|
get identityAnchorPath() {
|
|
8308
|
-
return
|
|
7949
|
+
return path10.join(this.identityDir, "identity-anchor.md");
|
|
8309
7950
|
}
|
|
8310
7951
|
get identityIncidentsDir() {
|
|
8311
|
-
return
|
|
7952
|
+
return path10.join(this.identityDir, "incidents");
|
|
8312
7953
|
}
|
|
8313
7954
|
get identityAuditsWeeklyDir() {
|
|
8314
|
-
return
|
|
7955
|
+
return path10.join(this.identityDir, "audits", "weekly");
|
|
8315
7956
|
}
|
|
8316
7957
|
get identityAuditsMonthlyDir() {
|
|
8317
|
-
return
|
|
7958
|
+
return path10.join(this.identityDir, "audits", "monthly");
|
|
8318
7959
|
}
|
|
8319
7960
|
get identityImprovementLoopsPath() {
|
|
8320
|
-
return
|
|
7961
|
+
return path10.join(this.identityDir, "improvement-loops.md");
|
|
8321
7962
|
}
|
|
8322
7963
|
get identityReflectionsPath() {
|
|
8323
|
-
return
|
|
7964
|
+
return path10.join(this.identityDir, "reflections.md");
|
|
8324
7965
|
}
|
|
8325
7966
|
get profilePath() {
|
|
8326
|
-
return
|
|
7967
|
+
return path10.join(this.baseDir, "profile.md");
|
|
8327
7968
|
}
|
|
8328
7969
|
get memoryActionsPath() {
|
|
8329
|
-
return
|
|
7970
|
+
return path10.join(this.stateDir, "memory-actions.jsonl");
|
|
8330
7971
|
}
|
|
8331
7972
|
get memoryLifecycleLedgerPath() {
|
|
8332
|
-
return
|
|
7973
|
+
return path10.join(this.stateDir, "memory-lifecycle-ledger.jsonl");
|
|
8333
7974
|
}
|
|
8334
7975
|
get compressionGuidelinesPath() {
|
|
8335
|
-
return
|
|
7976
|
+
return path10.join(this.stateDir, "compression-guidelines.md");
|
|
8336
7977
|
}
|
|
8337
7978
|
get compressionGuidelineDraftPath() {
|
|
8338
|
-
return
|
|
7979
|
+
return path10.join(this.stateDir, "compression-guidelines.draft.md");
|
|
8339
7980
|
}
|
|
8340
7981
|
get compressionGuidelineStatePath() {
|
|
8341
|
-
return
|
|
7982
|
+
return path10.join(this.stateDir, "compression-guideline-state.json");
|
|
8342
7983
|
}
|
|
8343
7984
|
get compressionGuidelineDraftStatePath() {
|
|
8344
|
-
return
|
|
7985
|
+
return path10.join(this.stateDir, "compression-guideline-draft-state.json");
|
|
8345
7986
|
}
|
|
8346
7987
|
get behaviorSignalsPath() {
|
|
8347
|
-
return
|
|
7988
|
+
return path10.join(this.stateDir, "behavior-signals.jsonl");
|
|
8348
7989
|
}
|
|
8349
7990
|
/**
|
|
8350
7991
|
* In-memory dedup key set for behavior-signals appends (issue #1909),
|
|
@@ -8376,7 +8017,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8376
8017
|
* governance sweeps can treat it uniformly.
|
|
8377
8018
|
*/
|
|
8378
8019
|
get bufferSurpriseLedgerPath() {
|
|
8379
|
-
return
|
|
8020
|
+
return path10.join(this.stateDir, "buffer-surprise-ledger.jsonl");
|
|
8380
8021
|
}
|
|
8381
8022
|
/**
|
|
8382
8023
|
* Entity alias table loaded from THIS store's config/aliases.json.
|
|
@@ -8437,7 +8078,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8437
8078
|
this.loadAliasesSync();
|
|
8438
8079
|
}
|
|
8439
8080
|
loadAliasesSync() {
|
|
8440
|
-
const aliasPath =
|
|
8081
|
+
const aliasPath = path10.join(this.baseDir, "config", "aliases.json");
|
|
8441
8082
|
this.userAliases = {};
|
|
8442
8083
|
const raw = readEntityAliasConfigSync(this.baseDir);
|
|
8443
8084
|
if (raw === void 0) return;
|
|
@@ -8472,22 +8113,22 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8472
8113
|
return completionFingerprint;
|
|
8473
8114
|
}
|
|
8474
8115
|
async ensureDirectories() {
|
|
8475
|
-
await
|
|
8116
|
+
await mkdir(this.baseDir, { recursive: true });
|
|
8476
8117
|
await validateRoots(this.baseDir, this.entitiesDir, this.stateDir, this.archiveDir);
|
|
8477
8118
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8478
|
-
await
|
|
8479
|
-
await
|
|
8480
|
-
await
|
|
8481
|
-
await
|
|
8482
|
-
await
|
|
8483
|
-
await
|
|
8484
|
-
await
|
|
8485
|
-
await
|
|
8486
|
-
await
|
|
8487
|
-
await
|
|
8488
|
-
await
|
|
8489
|
-
await
|
|
8490
|
-
await
|
|
8119
|
+
await mkdir(path10.join(this.factsDir, today), { recursive: true });
|
|
8120
|
+
await mkdir(path10.join(this.proceduresDir, today), { recursive: true });
|
|
8121
|
+
await mkdir(path10.join(this.reasoningTracesDir, today), { recursive: true });
|
|
8122
|
+
await mkdir(this.correctionsDir, { recursive: true });
|
|
8123
|
+
await mkdir(this.entitiesDir, { recursive: true });
|
|
8124
|
+
await mkdir(this.stateDir, { recursive: true });
|
|
8125
|
+
await mkdir(this.questionsDir, { recursive: true });
|
|
8126
|
+
await mkdir(this.artifactsDir, { recursive: true });
|
|
8127
|
+
await mkdir(this.identityDir, { recursive: true });
|
|
8128
|
+
await mkdir(this.identityIncidentsDir, { recursive: true });
|
|
8129
|
+
await mkdir(this.identityAuditsWeeklyDir, { recursive: true });
|
|
8130
|
+
await mkdir(this.identityAuditsMonthlyDir, { recursive: true });
|
|
8131
|
+
await mkdir(path10.join(this.baseDir, "config"), { recursive: true });
|
|
8491
8132
|
await this.entityCanonicalIdMigration.ensure();
|
|
8492
8133
|
if (this.hotMemoriesCacheEnabled && this.getMemoryCorpusVersion() === 0) {
|
|
8493
8134
|
this.bumpMemoryCorpusVersion();
|
|
@@ -8508,12 +8149,12 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8508
8149
|
*/
|
|
8509
8150
|
async resolveCategoryWritePath(category, id, today) {
|
|
8510
8151
|
if (category === "correction") {
|
|
8511
|
-
await
|
|
8512
|
-
return
|
|
8152
|
+
await mkdir(this.correctionsDir, { recursive: true });
|
|
8153
|
+
return path10.join(this.correctionsDir, `${id}.md`);
|
|
8513
8154
|
}
|
|
8514
|
-
const datedDir =
|
|
8515
|
-
await
|
|
8516
|
-
return
|
|
8155
|
+
const datedDir = path10.join(getCategoryDir(this.baseDir, category), today);
|
|
8156
|
+
await mkdir(datedDir, { recursive: true });
|
|
8157
|
+
return path10.join(datedDir, `${id}.md`);
|
|
8517
8158
|
}
|
|
8518
8159
|
async findExistingTombstoneBlockedMemory(content, category, sourceConnector) {
|
|
8519
8160
|
const identity = buildExplicitCaptureDedupKey(content, category, sourceConnector);
|
|
@@ -8675,7 +8316,7 @@ ${sanitized.text}
|
|
|
8675
8316
|
}
|
|
8676
8317
|
});
|
|
8677
8318
|
} catch (err) {
|
|
8678
|
-
await
|
|
8319
|
+
await unlink4(filePath).catch(() => void 0);
|
|
8679
8320
|
this.invalidateAllMemoriesCache();
|
|
8680
8321
|
await this.rebuildTombstoneBlockedCaptureAfterInvalidationForPath(filePath);
|
|
8681
8322
|
throw err;
|
|
@@ -8693,7 +8334,8 @@ ${sanitized.text}
|
|
|
8693
8334
|
id: duplicateBlocked.frontmatter.id,
|
|
8694
8335
|
tombstoneBlocked: true,
|
|
8695
8336
|
blockedBy: duplicateBlocked.frontmatter.blockedBy,
|
|
8696
|
-
duplicateOf: duplicateBlocked.frontmatter.id
|
|
8337
|
+
duplicateOf: duplicateBlocked.frontmatter.id,
|
|
8338
|
+
memory: duplicateBlocked
|
|
8697
8339
|
};
|
|
8698
8340
|
}
|
|
8699
8341
|
await this.patchHotMemoriesCache({ addedPath: filePath }, "memory-create");
|
|
@@ -8724,7 +8366,7 @@ ${sanitized.text}
|
|
|
8724
8366
|
}
|
|
8725
8367
|
}
|
|
8726
8368
|
log.debug(`wrote memory ${id} to ${filePath}`);
|
|
8727
|
-
return { id, tombstoneBlocked: tombstoneBlocked2, ...fm.blockedBy ? { blockedBy: fm.blockedBy } : {} };
|
|
8369
|
+
return { id, tombstoneBlocked: tombstoneBlocked2, ...fm.blockedBy ? { blockedBy: fm.blockedBy } : {}, memory: { path: filePath, frontmatter: fm, content: sanitized.text } };
|
|
8728
8370
|
}
|
|
8729
8371
|
/**
|
|
8730
8372
|
* Sealed-envelope write entry point (issue #1989 PR2).
|
|
@@ -8877,8 +8519,8 @@ ${sanitized.text}
|
|
|
8877
8519
|
await this.ensureDirectories();
|
|
8878
8520
|
const now = /* @__PURE__ */ new Date();
|
|
8879
8521
|
const day = now.toISOString().slice(0, 10);
|
|
8880
|
-
const dir =
|
|
8881
|
-
await
|
|
8522
|
+
const dir = path10.join(this.artifactsDir, day);
|
|
8523
|
+
await mkdir(dir, { recursive: true });
|
|
8882
8524
|
const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
8883
8525
|
const fm = {
|
|
8884
8526
|
id,
|
|
@@ -8903,7 +8545,7 @@ ${sanitized.text}
|
|
|
8903
8545
|
log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
8904
8546
|
return "";
|
|
8905
8547
|
}
|
|
8906
|
-
const filePath =
|
|
8548
|
+
const filePath = path10.join(dir, `${id}.md`);
|
|
8907
8549
|
await this.writeStorageSecureFile(filePath, `${serializeFrontmatter(fm)}
|
|
8908
8550
|
|
|
8909
8551
|
${sanitized.text}
|
|
@@ -9191,7 +8833,7 @@ ${sanitized.text}
|
|
|
9191
8833
|
* per-process in-memory cache safe across process boundaries.
|
|
9192
8834
|
*/
|
|
9193
8835
|
invalidateColdMemoriesCache() {
|
|
9194
|
-
const coldRoot =
|
|
8836
|
+
const coldRoot = path10.join(this.baseDir, "cold");
|
|
9195
8837
|
_StorageManager.coldMemoriesCache.delete(coldRoot);
|
|
9196
8838
|
this.bumpColdWriteVersion();
|
|
9197
8839
|
invalidateAllForDir(this.baseDir);
|
|
@@ -9311,7 +8953,7 @@ ${sanitized.text}
|
|
|
9311
8953
|
const correctionPaths = [];
|
|
9312
8954
|
const factPaths = [];
|
|
9313
8955
|
for (const filePath of filePaths) {
|
|
9314
|
-
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${
|
|
8956
|
+
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${path10.sep}`)) {
|
|
9315
8957
|
correctionPaths.push(filePath);
|
|
9316
8958
|
} else {
|
|
9317
8959
|
factPaths.push(filePath);
|
|
@@ -9374,7 +9016,7 @@ ${sanitized.text}
|
|
|
9374
9016
|
try {
|
|
9375
9017
|
const entries = await readdir6(dir, { withFileTypes: true });
|
|
9376
9018
|
for (const entry of entries) {
|
|
9377
|
-
const fullPath =
|
|
9019
|
+
const fullPath = path10.join(dir, entry.name);
|
|
9378
9020
|
if (entry.isDirectory()) {
|
|
9379
9021
|
await readDir(fullPath);
|
|
9380
9022
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -9417,7 +9059,7 @@ ${sanitized.text}
|
|
|
9417
9059
|
return this.rememberMemorySnapshot(await this.memoryReadStore.readMemoryByPath(filePath));
|
|
9418
9060
|
}
|
|
9419
9061
|
resolveTierRootDir(tier) {
|
|
9420
|
-
return tier === "cold" ?
|
|
9062
|
+
return tier === "cold" ? path10.join(this.baseDir, "cold") : this.baseDir;
|
|
9421
9063
|
}
|
|
9422
9064
|
resolveMemoryDateDir(memory) {
|
|
9423
9065
|
const preferred = memory.frontmatter.created || memory.frontmatter.updated;
|
|
@@ -9432,13 +9074,13 @@ ${sanitized.text}
|
|
|
9432
9074
|
buildTierMemoryPath(memory, tier) {
|
|
9433
9075
|
const root = this.resolveTierRootDir(tier);
|
|
9434
9076
|
if (this.isArtifactMemory(memory)) {
|
|
9435
|
-
return
|
|
9077
|
+
return path10.join(root, "artifacts", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
9436
9078
|
}
|
|
9437
9079
|
if (memory.frontmatter.category === "correction") {
|
|
9438
|
-
return
|
|
9080
|
+
return path10.join(root, "corrections", `${memory.frontmatter.id}.md`);
|
|
9439
9081
|
}
|
|
9440
9082
|
const dir = categoryDirName(memory.frontmatter.category);
|
|
9441
|
-
return
|
|
9083
|
+
return path10.join(root, dir, this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
9442
9084
|
}
|
|
9443
9085
|
async writeMemoryFileAtomic(targetPath, memory) {
|
|
9444
9086
|
const refIdsAtWrite = this.currentHistoricalIds();
|
|
@@ -9454,7 +9096,7 @@ ${memory.content}
|
|
|
9454
9096
|
{},
|
|
9455
9097
|
this.baseDir
|
|
9456
9098
|
);
|
|
9457
|
-
const priorDest = await
|
|
9099
|
+
const priorDest = await readFile2(targetPath).catch(() => null);
|
|
9458
9100
|
await persist();
|
|
9459
9101
|
if (typeof rawRef === "string") {
|
|
9460
9102
|
const refBeforeRepair = frontmatter.entityRef;
|
|
@@ -9469,7 +9111,7 @@ ${memory.content}
|
|
|
9469
9111
|
});
|
|
9470
9112
|
} catch (err) {
|
|
9471
9113
|
if (priorDest === null) {
|
|
9472
|
-
await
|
|
9114
|
+
await unlink4(targetPath).catch(() => void 0);
|
|
9473
9115
|
} else {
|
|
9474
9116
|
await writeFile2(targetPath, priorDest).catch(() => void 0);
|
|
9475
9117
|
}
|
|
@@ -9516,8 +9158,8 @@ ${memory.content}
|
|
|
9516
9158
|
memory.frontmatter.entityRef = current.frontmatter.entityRef;
|
|
9517
9159
|
}
|
|
9518
9160
|
durable = true;
|
|
9519
|
-
const sourcePath =
|
|
9520
|
-
const destPath =
|
|
9161
|
+
const sourcePath = path10.resolve(current.path);
|
|
9162
|
+
const destPath = path10.resolve(targetPath);
|
|
9521
9163
|
if (sourcePath !== destPath) {
|
|
9522
9164
|
await recordArchiveDelete2(this.baseDir, current.path, () => this.deleteManagedStorageFile(current.path));
|
|
9523
9165
|
this.invalidateAllMemoriesCache();
|
|
@@ -9541,8 +9183,8 @@ ${memory.content}
|
|
|
9541
9183
|
}
|
|
9542
9184
|
async migrateMemoryToTier(memory, targetTier) {
|
|
9543
9185
|
const targetPath = this.buildTierMemoryPath(memory, targetTier);
|
|
9544
|
-
const sourcePath =
|
|
9545
|
-
const destPath =
|
|
9186
|
+
const sourcePath = path10.resolve(memory.path);
|
|
9187
|
+
const destPath = path10.resolve(targetPath);
|
|
9546
9188
|
if (sourcePath === destPath) {
|
|
9547
9189
|
return { changed: false, targetPath };
|
|
9548
9190
|
}
|
|
@@ -9552,7 +9194,7 @@ ${memory.content}
|
|
|
9552
9194
|
return { changed, targetPath };
|
|
9553
9195
|
}
|
|
9554
9196
|
get archiveDir() {
|
|
9555
|
-
return
|
|
9197
|
+
return path10.join(this.baseDir, "archive");
|
|
9556
9198
|
}
|
|
9557
9199
|
/**
|
|
9558
9200
|
* Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.
|
|
@@ -9565,8 +9207,8 @@ ${memory.content}
|
|
|
9565
9207
|
try {
|
|
9566
9208
|
const now = lifecycle?.at ?? /* @__PURE__ */ new Date();
|
|
9567
9209
|
const today = now.toISOString().slice(0, 10);
|
|
9568
|
-
const destDir =
|
|
9569
|
-
await
|
|
9210
|
+
const destDir = path10.join(this.archiveDir, today);
|
|
9211
|
+
await mkdir(destDir, { recursive: true });
|
|
9570
9212
|
const refIdsAtWrite = this.currentHistoricalIds();
|
|
9571
9213
|
const updatedFm = canonicalizeEntityRefOption(
|
|
9572
9214
|
{
|
|
@@ -9581,7 +9223,7 @@ ${memory.content}
|
|
|
9581
9223
|
|
|
9582
9224
|
${current.content}
|
|
9583
9225
|
`;
|
|
9584
|
-
const destPath =
|
|
9226
|
+
const destPath = path10.join(destDir, path10.basename(current.path));
|
|
9585
9227
|
const priorDest = await this.readStorageSecureFile(destPath).catch(() => null);
|
|
9586
9228
|
await recordArchiveWrite(this.baseDir, destPath, () => this.writeStorageSecureFile(destPath, fileContent));
|
|
9587
9229
|
if (typeof current.frontmatter.entityRef === "string") {
|
|
@@ -9598,7 +9240,7 @@ ${current.content}
|
|
|
9598
9240
|
await recordArchiveDelete2(
|
|
9599
9241
|
this.baseDir,
|
|
9600
9242
|
destPath,
|
|
9601
|
-
() =>
|
|
9243
|
+
() => unlink4(destPath).then(
|
|
9602
9244
|
() => true,
|
|
9603
9245
|
() => false
|
|
9604
9246
|
)
|
|
@@ -9814,7 +9456,7 @@ ${memory.content}
|
|
|
9814
9456
|
`;
|
|
9815
9457
|
await this.writeTombstoneBlockedFrontmatter(memory, fileContent, updated, async () => {
|
|
9816
9458
|
this.invalidateAllMemoriesCache();
|
|
9817
|
-
if (memory.path.includes(`${
|
|
9459
|
+
if (memory.path.includes(`${path10.sep}cold${path10.sep}`)) {
|
|
9818
9460
|
this.invalidateColdMemoriesCache();
|
|
9819
9461
|
}
|
|
9820
9462
|
});
|
|
@@ -9825,7 +9467,7 @@ ${memory.content}
|
|
|
9825
9467
|
});
|
|
9826
9468
|
}
|
|
9827
9469
|
await this.patchHotMemoriesCache({ addedPath: memory.path });
|
|
9828
|
-
if (memory.path.includes(`${
|
|
9470
|
+
if (memory.path.includes(`${path10.sep}cold${path10.sep}`)) {
|
|
9829
9471
|
this.invalidateColdMemoriesCache();
|
|
9830
9472
|
}
|
|
9831
9473
|
try {
|
|
@@ -9906,7 +9548,7 @@ ${memory.content}
|
|
|
9906
9548
|
return deleted;
|
|
9907
9549
|
}
|
|
9908
9550
|
async loadBuffer() {
|
|
9909
|
-
const bufferPath =
|
|
9551
|
+
const bufferPath = path10.join(this.stateDir, "buffer.json");
|
|
9910
9552
|
try {
|
|
9911
9553
|
const raw = await this.readStorageSecureFile(bufferPath);
|
|
9912
9554
|
return JSON.parse(raw);
|
|
@@ -9918,11 +9560,11 @@ ${memory.content}
|
|
|
9918
9560
|
}
|
|
9919
9561
|
async saveBuffer(state) {
|
|
9920
9562
|
await this.ensureDirectories();
|
|
9921
|
-
const bufferPath =
|
|
9563
|
+
const bufferPath = path10.join(this.stateDir, "buffer.json");
|
|
9922
9564
|
await this.writeStorageSecureFile(bufferPath, JSON.stringify(state, null, 2));
|
|
9923
9565
|
}
|
|
9924
9566
|
async loadMeta() {
|
|
9925
|
-
const metaPath =
|
|
9567
|
+
const metaPath = path10.join(this.stateDir, "meta.json");
|
|
9926
9568
|
try {
|
|
9927
9569
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
9928
9570
|
const parsed = JSON.parse(raw);
|
|
@@ -9955,7 +9597,7 @@ ${memory.content}
|
|
|
9955
9597
|
}
|
|
9956
9598
|
async saveMeta(state) {
|
|
9957
9599
|
await this.ensureDirectories();
|
|
9958
|
-
const metaPath =
|
|
9600
|
+
const metaPath = path10.join(this.stateDir, "meta.json");
|
|
9959
9601
|
await this.writeStorageSecureFile(metaPath, JSON.stringify(state, null, 2));
|
|
9960
9602
|
}
|
|
9961
9603
|
async appendMemoryActionEvents(events) {
|
|
@@ -10019,7 +9661,7 @@ ${memory.content}
|
|
|
10019
9661
|
},
|
|
10020
9662
|
(payload) => this.appendStorageSecureFile(target, payload),
|
|
10021
9663
|
async () => {
|
|
10022
|
-
await
|
|
9664
|
+
await mkdir(path10.dirname(target), { recursive: true });
|
|
10023
9665
|
}
|
|
10024
9666
|
);
|
|
10025
9667
|
}
|
|
@@ -10117,7 +9759,7 @@ ${memory.content}
|
|
|
10117
9759
|
async appendReextractJobs(events) {
|
|
10118
9760
|
if (events.length === 0) return 0;
|
|
10119
9761
|
await this.ensureDirectories();
|
|
10120
|
-
const filePath =
|
|
9762
|
+
const filePath = path10.join(this.stateDir, "reextract-jobs.jsonl");
|
|
10121
9763
|
const lines = events.map((event) => JSON.stringify(event)).join("\n") + "\n";
|
|
10122
9764
|
try {
|
|
10123
9765
|
await this.appendStorageSecureFile(filePath, lines);
|
|
@@ -10130,7 +9772,7 @@ ${memory.content}
|
|
|
10130
9772
|
}
|
|
10131
9773
|
async readReextractJobs(limit = 200) {
|
|
10132
9774
|
const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1e3, Math.floor(limit))) : 200;
|
|
10133
|
-
const filePath =
|
|
9775
|
+
const filePath = path10.join(this.stateDir, "reextract-jobs.jsonl");
|
|
10134
9776
|
try {
|
|
10135
9777
|
const raw = await this.readStorageSecureFile(filePath);
|
|
10136
9778
|
const lines = raw.split("\n").filter((line) => line.trim().length > 0);
|
|
@@ -10279,7 +9921,7 @@ ${memory.content}
|
|
|
10279
9921
|
return false;
|
|
10280
9922
|
}
|
|
10281
9923
|
if (draftState.contentHash) {
|
|
10282
|
-
const contentHash =
|
|
9924
|
+
const contentHash = createHash6("sha256").update(draftContent).digest("hex");
|
|
10283
9925
|
if (contentHash !== draftState.contentHash) return false;
|
|
10284
9926
|
}
|
|
10285
9927
|
await this.writeCompressionGuidelines(draftContent);
|
|
@@ -10288,8 +9930,8 @@ ${memory.content}
|
|
|
10288
9930
|
activationState: "active"
|
|
10289
9931
|
});
|
|
10290
9932
|
await Promise.all([
|
|
10291
|
-
|
|
10292
|
-
|
|
9933
|
+
unlink4(this.compressionGuidelineDraftPath).catch(() => void 0),
|
|
9934
|
+
unlink4(this.compressionGuidelineDraftStatePath).catch(() => void 0)
|
|
10293
9935
|
]);
|
|
10294
9936
|
return true;
|
|
10295
9937
|
}
|
|
@@ -10341,7 +9983,7 @@ ${memory.content}
|
|
|
10341
9983
|
return `${prefix}-${ts}-${rand}`;
|
|
10342
9984
|
}
|
|
10343
9985
|
async writeQuestion(question, context, priority) {
|
|
10344
|
-
await
|
|
9986
|
+
await mkdir(this.questionsDir, { recursive: true });
|
|
10345
9987
|
const id = this.generateId("q");
|
|
10346
9988
|
const frontmatter = {
|
|
10347
9989
|
id,
|
|
@@ -10357,7 +9999,7 @@ ${question}
|
|
|
10357
9999
|
|
|
10358
10000
|
**Context:** ${context}
|
|
10359
10001
|
`;
|
|
10360
|
-
const filePath =
|
|
10002
|
+
const filePath = path10.join(this.questionsDir, `${id}.md`);
|
|
10361
10003
|
await this.writeStorageSecureFile(filePath, content);
|
|
10362
10004
|
log.debug(`wrote question ${id} to ${filePath}`);
|
|
10363
10005
|
this.invalidateQuestionsCache();
|
|
@@ -10375,7 +10017,7 @@ ${question}
|
|
|
10375
10017
|
if (!match) return null;
|
|
10376
10018
|
const frontmatterStr = match[1];
|
|
10377
10019
|
const body = match[2].trim();
|
|
10378
|
-
const id = this.extractFrontmatterValue(frontmatterStr, "id") ??
|
|
10020
|
+
const id = this.extractFrontmatterValue(frontmatterStr, "id") ?? path10.basename(filePath, ".md");
|
|
10379
10021
|
const created = this.extractFrontmatterValue(frontmatterStr, "created") ?? "";
|
|
10380
10022
|
const priority = parseFloat(this.extractFrontmatterValue(frontmatterStr, "priority") ?? "0.5");
|
|
10381
10023
|
const resolved = this.extractFrontmatterValue(frontmatterStr, "resolved") === "true";
|
|
@@ -10409,7 +10051,7 @@ ${question}
|
|
|
10409
10051
|
async readIdentity(workspaceDir, namespace) {
|
|
10410
10052
|
const identityPath = this.identityFilePath(workspaceDir, namespace);
|
|
10411
10053
|
try {
|
|
10412
|
-
return await
|
|
10054
|
+
return await readFile2(identityPath, "utf-8");
|
|
10413
10055
|
} catch {
|
|
10414
10056
|
return "";
|
|
10415
10057
|
}
|
|
@@ -10427,15 +10069,15 @@ ${question}
|
|
|
10427
10069
|
const identityPath = this.identityFilePath(workspaceDir, opts?.namespace);
|
|
10428
10070
|
let existing = "";
|
|
10429
10071
|
try {
|
|
10430
|
-
existing = await
|
|
10072
|
+
existing = await readFile2(identityPath, "utf-8");
|
|
10431
10073
|
} catch {
|
|
10432
10074
|
}
|
|
10433
10075
|
const hygiene = opts?.hygiene;
|
|
10434
|
-
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(
|
|
10076
|
+
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(path10.basename(identityPath));
|
|
10435
10077
|
if (rotateEnabled) {
|
|
10436
10078
|
const maxBytes = hygiene.rotateMaxBytes;
|
|
10437
10079
|
if (existing.length > maxBytes) {
|
|
10438
|
-
const archiveDir =
|
|
10080
|
+
const archiveDir = path10.join(workspaceDir, hygiene.archiveDir);
|
|
10439
10081
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
10440
10082
|
filePath: identityPath,
|
|
10441
10083
|
archiveDir,
|
|
@@ -10487,7 +10129,7 @@ ${reflection}
|
|
|
10487
10129
|
}
|
|
10488
10130
|
}
|
|
10489
10131
|
async writeIdentityReflections(content) {
|
|
10490
|
-
await
|
|
10132
|
+
await mkdir(this.identityDir, { recursive: true });
|
|
10491
10133
|
await this.writeStorageSecureFile(this.identityReflectionsPath, content);
|
|
10492
10134
|
}
|
|
10493
10135
|
async appendIdentityReflection(reflection) {
|
|
@@ -10519,7 +10161,7 @@ ${reflection}
|
|
|
10519
10161
|
|
|
10520
10162
|
${reflection}
|
|
10521
10163
|
`;
|
|
10522
|
-
await
|
|
10164
|
+
await mkdir(this.identityDir, { recursive: true });
|
|
10523
10165
|
await this.writeStorageSecureFile(this.identityReflectionsPath, `${existing.trimEnd()}${section}`);
|
|
10524
10166
|
log.debug(`appended namespace-local reflection to ${this.identityReflectionsPath}`);
|
|
10525
10167
|
}
|
|
@@ -10575,7 +10217,7 @@ ${reflection}
|
|
|
10575
10217
|
const rightTs = latestEntityTimelineTimestamp(right.entity) ?? "";
|
|
10576
10218
|
return compareEntityTimestamps(rightTs, leftTs);
|
|
10577
10219
|
}).map(({ entityName }) => entityName);
|
|
10578
|
-
await
|
|
10220
|
+
await mkdir(this.stateDir, { recursive: true });
|
|
10579
10221
|
await this.writeStorageSecureFile(
|
|
10580
10222
|
this.entitySynthesisQueuePath,
|
|
10581
10223
|
JSON.stringify(
|
|
@@ -10595,7 +10237,7 @@ ${reflection}
|
|
|
10595
10237
|
if (queue.length === 0) return;
|
|
10596
10238
|
const removals = new Set(entityNames);
|
|
10597
10239
|
const nextQueue = queue.filter((name) => !removals.has(name));
|
|
10598
|
-
await
|
|
10240
|
+
await mkdir(this.stateDir, { recursive: true });
|
|
10599
10241
|
await this.writeStorageSecureFile(
|
|
10600
10242
|
this.entitySynthesisQueuePath,
|
|
10601
10243
|
JSON.stringify(
|
|
@@ -10695,14 +10337,14 @@ ${reflection}
|
|
|
10695
10337
|
if (entries.length === 0) return 0;
|
|
10696
10338
|
const memories = await this.readAllMemories();
|
|
10697
10339
|
const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));
|
|
10698
|
-
const memoryPathMap = new Map(memories.map((m) => [
|
|
10340
|
+
const memoryPathMap = new Map(memories.map((m) => [path10.resolve(m.path), m]));
|
|
10699
10341
|
let updated = 0;
|
|
10700
10342
|
const prevVersion = this.getMemoryCorpusVersion();
|
|
10701
10343
|
const keyId = this.hotCacheKeyId();
|
|
10702
10344
|
const warm = this.hotMemoriesCacheEnabled && getCachedMemories(this.baseDir, prevVersion, keyId, this.hotCacheTtlMs()) !== null;
|
|
10703
10345
|
const appliedPatches = /* @__PURE__ */ new Map();
|
|
10704
10346
|
for (const entry of entries) {
|
|
10705
|
-
const memory = entry.memoryPath ? memoryPathMap.get(
|
|
10347
|
+
const memory = entry.memoryPath ? memoryPathMap.get(path10.resolve(entry.memoryPath)) : memoryMap.get(entry.memoryId);
|
|
10706
10348
|
if (!memory) continue;
|
|
10707
10349
|
try {
|
|
10708
10350
|
const applied = await this.withTombstoneBlockedMemoryPathLock(memory.path, async (current) => {
|
|
@@ -10733,7 +10375,7 @@ ${current.content}
|
|
|
10733
10375
|
if (warm) {
|
|
10734
10376
|
updateCacheOnWrite(this.baseDir, { ...applied.current, frontmatter: applied.newFm }, keyId);
|
|
10735
10377
|
}
|
|
10736
|
-
appliedPatches.set(
|
|
10378
|
+
appliedPatches.set(path10.resolve(memory.path), {
|
|
10737
10379
|
accessCount: entry.newCount,
|
|
10738
10380
|
lastAccessed: entry.lastAccessed
|
|
10739
10381
|
});
|
|
@@ -10749,7 +10391,7 @@ ${current.content}
|
|
|
10749
10391
|
const cur = getCachedMemories(this.baseDir, prevVersion, keyId);
|
|
10750
10392
|
if (cur) {
|
|
10751
10393
|
const reapplied = cur.map((m) => {
|
|
10752
|
-
const patch = appliedPatches.get(
|
|
10394
|
+
const patch = appliedPatches.get(path10.resolve(m.path));
|
|
10753
10395
|
return patch ? {
|
|
10754
10396
|
...m,
|
|
10755
10397
|
frontmatter: { ...m.frontmatter, accessCount: patch.accessCount, lastAccessed: patch.lastAccessed }
|
|
@@ -10763,20 +10405,15 @@ ${current.content}
|
|
|
10763
10405
|
}
|
|
10764
10406
|
return updated;
|
|
10765
10407
|
}
|
|
10766
|
-
/**
|
|
10767
|
-
* Get a memory by its ID.
|
|
10768
|
-
*/
|
|
10769
10408
|
async getMemoryById(id) {
|
|
10770
10409
|
const memories = await this.readAllMemories();
|
|
10771
10410
|
return memories.find((m) => m.frontmatter.id === id) ?? null;
|
|
10772
10411
|
}
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
* for citation usage tracking and other existence checks.
|
|
10779
|
-
*/
|
|
10412
|
+
async getMemoryByIdIncludingArchived(id) {
|
|
10413
|
+
const active = await this.getMemoryById(id);
|
|
10414
|
+
return active ?? (await this.readAllColdMemories()).find((memory) => memory.frontmatter.id === id) ?? (await this.readArchivedMemories()).find((memory) => memory.frontmatter.id === id) ?? null;
|
|
10415
|
+
}
|
|
10416
|
+
/** Resolve existing active memory IDs through a lightweight directory scan. */
|
|
10780
10417
|
async findExistingMemoryPaths(ids, preferredPaths = /* @__PURE__ */ new Map()) {
|
|
10781
10418
|
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
10782
10419
|
const wantedIds = new Set(ids);
|
|
@@ -10784,7 +10421,7 @@ ${current.content}
|
|
|
10784
10421
|
const pathsById = /* @__PURE__ */ new Map();
|
|
10785
10422
|
const filePathsById = /* @__PURE__ */ new Map();
|
|
10786
10423
|
for (const filePath of filePaths) {
|
|
10787
|
-
const memoryId =
|
|
10424
|
+
const memoryId = path10.basename(filePath, ".md");
|
|
10788
10425
|
if (!wantedIds.has(memoryId)) continue;
|
|
10789
10426
|
const paths = filePathsById.get(memoryId) ?? [];
|
|
10790
10427
|
paths.push(filePath);
|
|
@@ -10796,7 +10433,7 @@ ${current.content}
|
|
|
10796
10433
|
const preferredMatches = [];
|
|
10797
10434
|
for (const preferredPath of preferred) {
|
|
10798
10435
|
const directCandidates = new Set(qmdResultPathCandidates(this.baseDir, preferredPath));
|
|
10799
|
-
const directMatch = existingPaths.find((filePath) => directCandidates.has(
|
|
10436
|
+
const directMatch = existingPaths.find((filePath) => directCandidates.has(path10.resolve(filePath)));
|
|
10800
10437
|
if (directMatch) {
|
|
10801
10438
|
preferredMatches.push(directMatch);
|
|
10802
10439
|
continue;
|
|
@@ -10808,7 +10445,7 @@ ${current.content}
|
|
|
10808
10445
|
candidates.add(candidate);
|
|
10809
10446
|
}
|
|
10810
10447
|
}
|
|
10811
|
-
const match = existingPaths.find((filePath) => candidates.has(
|
|
10448
|
+
const match = existingPaths.find((filePath) => candidates.has(path10.resolve(filePath)));
|
|
10812
10449
|
if (match) preferredMatches.push(match);
|
|
10813
10450
|
}
|
|
10814
10451
|
if (preferredMatches.length > 0) {
|
|
@@ -10862,7 +10499,8 @@ ${current.content}
|
|
|
10862
10499
|
accessCount: memory.frontmatter.accessCount,
|
|
10863
10500
|
lastAccessed: memory.frontmatter.lastAccessed,
|
|
10864
10501
|
tags: normalizeProjectionTags(memory.frontmatter.tags),
|
|
10865
|
-
preview: normalizeProjectionPreview(memory.content)
|
|
10502
|
+
preview: normalizeProjectionPreview(memory.content),
|
|
10503
|
+
privateRecord: isSupportPassportPrivateMemory(memory)
|
|
10866
10504
|
};
|
|
10867
10505
|
}
|
|
10868
10506
|
async getMemoryTimeline(memoryId, limit = 200) {
|
|
@@ -10997,7 +10635,7 @@ ${sanitized.text}
|
|
|
10997
10635
|
}
|
|
10998
10636
|
if (!oldMemory) return false;
|
|
10999
10637
|
const requireActiveAtWrite = options.requireActive === true || inferMemoryStatus(oldMemory.frontmatter, toMemoryPathRel(this.baseDir, oldMemory.path)) === "active";
|
|
11000
|
-
const operationId =
|
|
10638
|
+
const operationId = createHash6("sha256").update(
|
|
11001
10639
|
JSON.stringify({
|
|
11002
10640
|
oldMemoryId,
|
|
11003
10641
|
newMemoryId,
|
|
@@ -11081,6 +10719,8 @@ ${current.content}
|
|
|
11081
10719
|
exactReplay,
|
|
11082
10720
|
currentBefore,
|
|
11083
10721
|
updatedFm,
|
|
10722
|
+
actor: options.actor,
|
|
10723
|
+
audit: options.audit,
|
|
11084
10724
|
citationTemplate: this.citationTemplate,
|
|
11085
10725
|
correctionsDir: this.correctionsDir,
|
|
11086
10726
|
readMemoryByPath: (filePath) => this.readMemoryByPath(filePath),
|
|
@@ -11104,7 +10744,7 @@ ${current.content}
|
|
|
11104
10744
|
memoryId: oldMemoryId,
|
|
11105
10745
|
eventType: "superseded",
|
|
11106
10746
|
timestamp: supersededAt,
|
|
11107
|
-
actor: "storage.supersedeMemory",
|
|
10747
|
+
actor: options.actor ?? "storage.supersedeMemory",
|
|
11108
10748
|
reasonCode: reason,
|
|
11109
10749
|
before: exactReplay ? { ...beforeState, status: "active" } : beforeState,
|
|
11110
10750
|
after: afterState,
|
|
@@ -11124,11 +10764,11 @@ ${current.content}
|
|
|
11124
10764
|
}
|
|
11125
10765
|
}
|
|
11126
10766
|
get summariesDir() {
|
|
11127
|
-
return
|
|
10767
|
+
return path10.join(this.baseDir, "summaries");
|
|
11128
10768
|
}
|
|
11129
10769
|
async writeSummary(summary) {
|
|
11130
|
-
await
|
|
11131
|
-
const filePath =
|
|
10770
|
+
await mkdir(this.summariesDir, { recursive: true });
|
|
10771
|
+
const filePath = path10.join(this.summariesDir, `${summary.id}.json`);
|
|
11132
10772
|
await this.writeStorageSecureFile(filePath, JSON.stringify(summary, null, 2));
|
|
11133
10773
|
log.debug(`wrote summary ${summary.id}`);
|
|
11134
10774
|
}
|
|
@@ -11138,7 +10778,7 @@ ${current.content}
|
|
|
11138
10778
|
const summaries = [];
|
|
11139
10779
|
for (const file of files) {
|
|
11140
10780
|
if (!file.endsWith(".json")) continue;
|
|
11141
|
-
const filePath =
|
|
10781
|
+
const filePath = path10.join(this.summariesDir, file);
|
|
11142
10782
|
const raw = await this.readStorageSecureFile(filePath);
|
|
11143
10783
|
summaries.push(JSON.parse(raw));
|
|
11144
10784
|
}
|
|
@@ -11208,8 +10848,8 @@ ${current.content}
|
|
|
11208
10848
|
return archived;
|
|
11209
10849
|
}
|
|
11210
10850
|
async saveTopics(topics) {
|
|
11211
|
-
const metaPath =
|
|
11212
|
-
await
|
|
10851
|
+
const metaPath = path10.join(this.stateDir, "topics.json");
|
|
10852
|
+
await mkdir(this.stateDir, { recursive: true });
|
|
11213
10853
|
await this.writeStorageSecureFile(
|
|
11214
10854
|
metaPath,
|
|
11215
10855
|
JSON.stringify({ topics, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
@@ -11217,7 +10857,7 @@ ${current.content}
|
|
|
11217
10857
|
log.debug(`saved ${topics.length} topic scores`);
|
|
11218
10858
|
}
|
|
11219
10859
|
async loadTopics() {
|
|
11220
|
-
const metaPath =
|
|
10860
|
+
const metaPath = path10.join(this.stateDir, "topics.json");
|
|
11221
10861
|
try {
|
|
11222
10862
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
11223
10863
|
return JSON.parse(raw);
|
|
@@ -11332,4 +10972,4 @@ export {
|
|
|
11332
10972
|
isValidBufferSurpriseEvent,
|
|
11333
10973
|
StorageManager3 as StorageManager
|
|
11334
10974
|
};
|
|
11335
|
-
//# sourceMappingURL=chunk-
|
|
10975
|
+
//# sourceMappingURL=chunk-M4YHAODQ.js.map
|