@remnic/core 9.7.8 → 9.7.9
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 +6 -6
- package/dist/access-admin-ops-surface.js +31 -29
- package/dist/access-audit.js +2 -2
- package/dist/access-boundary.d.ts +6 -6
- package/dist/access-boundary.js +32 -30
- package/dist/access-cli.js +88 -86
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +6 -6
- package/dist/access-http.js +39 -37
- package/dist/access-identity-continuity-surface.d.ts +5 -5
- package/dist/access-identity-continuity-surface.js +31 -29
- package/dist/access-lcm-surface.d.ts +6 -6
- package/dist/access-lcm-surface.js +31 -29
- package/dist/access-mcp.d.ts +6 -6
- package/dist/access-mcp.js +36 -34
- package/dist/access-observe-write-surface.d.ts +6 -6
- package/dist/access-observe-write-surface.js +31 -29
- package/dist/access-operations-batch.js +34 -32
- package/dist/access-operations.d.ts +9 -9
- package/dist/access-operations.js +35 -33
- package/dist/access-recall-surface.d.ts +6 -6
- package/dist/access-recall-surface.js +31 -29
- package/dist/access-schema.d.ts +64 -64
- package/dist/{access-service-CxDZXTKt.d.ts → access-service-DSuzikHQ.d.ts} +4 -4
- package/dist/access-service.d.ts +6 -6
- package/dist/access-service.js +31 -29
- package/dist/access-surface-catalog.d.ts +6 -6
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/{auto-sync-676N6N6Y.js → auto-sync-AAMTVZMK.js} +5 -5
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +5 -5
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +14 -12
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +2 -2
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-merge-GK5E647P.js → capsule-merge-Z2HUO6IK.js} +10 -2
- package/dist/capsule-merge-Z2HUO6IK.js.map +1 -0
- package/dist/{catalog-DzU9HowE.d.ts → catalog-BNwjACa5.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 +15 -13
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-TZJVTH3F.js → chunk-27VEKQQA.js} +14 -14
- package/dist/{chunk-JO5AT6QT.js → chunk-3ZVFLMFQ.js} +1 -1
- package/dist/chunk-3ZVFLMFQ.js.map +1 -0
- package/dist/{chunk-AD2KK5MT.js → chunk-5CFHYQU3.js} +9 -3
- package/dist/chunk-5CFHYQU3.js.map +1 -0
- package/dist/{chunk-7XH7VJN4.js → chunk-5S7Z5SHA.js} +2 -2
- package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
- package/dist/{chunk-EJCVMPIM.js → chunk-7LMEY5KZ.js} +15 -1
- package/dist/chunk-7LMEY5KZ.js.map +1 -0
- package/dist/{chunk-3F4N4WDH.js → chunk-AHLPZ2SF.js} +2 -2
- package/dist/{chunk-AH3M6F4X.js → chunk-CDGGQGUU.js} +2 -2
- package/dist/{chunk-ZHKD4EZM.js → chunk-CK6RI52P.js} +3 -3
- package/dist/{chunk-6C35R7P4.js → chunk-DJCKXI4M.js} +2 -2
- package/dist/{chunk-GL3SMLMZ.js → chunk-DLPXS7BE.js} +109 -85
- package/dist/chunk-DLPXS7BE.js.map +1 -0
- package/dist/{chunk-NMMKRVUF.js → chunk-EIKBKQ6L.js} +6 -6
- package/dist/{chunk-O3BZ6PFY.js → chunk-F3FC7SMO.js} +2 -2
- package/dist/{chunk-ZW6OKHVX.js → chunk-FKCJH7KP.js} +2 -2
- package/dist/{chunk-DQPPRXFO.js → chunk-HQ7QZJM5.js} +2 -2
- package/dist/{chunk-UYZUJ4EB.js → chunk-I2THZUAF.js} +2 -2
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/{chunk-KIPLG7S7.js → chunk-JKLJ6A7W.js} +2 -2
- package/dist/{chunk-HXDKC3BI.js → chunk-JU3GHO6J.js} +2 -2
- package/dist/{chunk-74MJH7I3.js → chunk-KGNFFCZJ.js} +12 -3
- package/dist/chunk-KGNFFCZJ.js.map +1 -0
- package/dist/{chunk-Q6JPMCPO.js → chunk-KKASNHGF.js} +62 -57
- package/dist/chunk-KKASNHGF.js.map +1 -0
- package/dist/{chunk-R2SJDIPO.js → chunk-KPXAJ77O.js} +9 -7
- package/dist/chunk-KPXAJ77O.js.map +1 -0
- package/dist/{chunk-SYNYI4ZM.js → chunk-L5HJQC36.js} +2 -2
- package/dist/{chunk-VXMWDXIJ.js → chunk-LC7OODWZ.js} +2 -2
- package/dist/{chunk-CNWC274T.js → chunk-MLT5EG6K.js} +28 -28
- package/dist/{chunk-M5QKGHCR.js → chunk-OC35KQIN.js} +6 -2
- package/dist/chunk-OC35KQIN.js.map +1 -0
- package/dist/chunk-OKUEZOGW.js +27 -0
- package/dist/chunk-OKUEZOGW.js.map +1 -0
- package/dist/{chunk-PKGWJFNR.js → chunk-OVMS3DCB.js} +2 -2
- package/dist/chunk-PDJTHRAW.js +36 -0
- package/dist/chunk-PDJTHRAW.js.map +1 -0
- package/dist/{chunk-ZUFJ7ZTR.js → chunk-PHXCPVSX.js} +6 -2
- package/dist/chunk-PHXCPVSX.js.map +1 -0
- package/dist/{chunk-57INMZ6F.js → chunk-POUD5BLV.js} +2 -2
- package/dist/{chunk-KTOH7EJE.js → chunk-PV7E2FGY.js} +307 -43
- package/dist/chunk-PV7E2FGY.js.map +1 -0
- package/dist/{chunk-LRGSLV7M.js → chunk-PYHOAXTI.js} +4 -4
- package/dist/{chunk-WKE4VXSZ.js → chunk-QKVX4Y6D.js} +2 -2
- package/dist/{chunk-FXGC5UUH.js → chunk-RT7IP3D3.js} +2 -2
- package/dist/{chunk-CHVU4RE5.js → chunk-SKXBOZDF.js} +3 -3
- package/dist/{chunk-TVRPRFUB.js → chunk-TY43GBX2.js} +9 -7
- package/dist/chunk-TY43GBX2.js.map +1 -0
- package/dist/{chunk-UVIQHSS7.js → chunk-UP25ZZCN.js} +9 -3
- package/dist/chunk-UP25ZZCN.js.map +1 -0
- package/dist/{chunk-GKCCHHZK.js → chunk-UXKMMNJD.js} +4 -4
- package/dist/{chunk-XFTPUXCE.js → chunk-UXWGPODH.js} +4 -4
- package/dist/{chunk-2FSHROYK.js → chunk-V53GJUSL.js} +8 -8
- package/dist/{chunk-LKT755LP.js → chunk-VA4WSW54.js} +2 -2
- package/dist/{chunk-FYKIEOG6.js → chunk-VCFADTFS.js} +3 -3
- package/dist/{chunk-VF4XKTX3.js → chunk-VZ5OJE4X.js} +10 -2
- package/dist/chunk-VZ5OJE4X.js.map +1 -0
- package/dist/{chunk-AWJ2FHCF.js → chunk-X47LWMKA.js} +49 -21
- package/dist/chunk-X47LWMKA.js.map +1 -0
- package/dist/{chunk-VMGMY2AI.js → chunk-XG5CGR3K.js} +8 -8
- package/dist/{chunk-VMGMY2AI.js.map → chunk-XG5CGR3K.js.map} +1 -1
- package/dist/{chunk-T7VNN3ZM.js → chunk-XVLEGMJI.js} +2 -2
- package/dist/{chunk-CRFTLUWT.js → chunk-Y5U35ZVS.js} +2 -2
- package/dist/{chunk-UHGHTOR5.js → chunk-YGAOLHKN.js} +7 -7
- package/dist/{chunk-QDCJNRKK.js → chunk-YXOAQAH2.js} +3 -3
- package/dist/{cli-BqyGVyOe.d.ts → cli-DACyuK8-.d.ts} +5 -5
- package/dist/cli.d.ts +8 -8
- package/dist/cli.js +65 -63
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +14 -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 +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +14 -12
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +14 -12
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-provenance-check.js +6 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/consolidation-undo.js +8 -1
- package/dist/consolidation-undo.js.map +1 -1
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/conversation-index/backend.d.ts +1 -1
- 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/day-summary.d.ts +1 -1
- package/dist/delinearize.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 +14 -12
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +5 -5
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-faithfulness.js +3 -3
- 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 +3 -3
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +3 -3
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/fallback-llm.js +2 -2
- package/dist/{forget-KHF7A44H.js → forget-CQCLB5LB.js} +2 -2
- 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-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +19 -0
- package/dist/in-flight-reads.js +16 -0
- package/dist/in-flight-reads.js.map +1 -0
- package/dist/index.d.ts +13 -13
- package/dist/index.js +105 -103
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +7 -7
- 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 +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +14 -12
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -12
- package/dist/maintenance/rebuild-memory-projection.js +15 -13
- package/dist/mcp-memory-inspector-app.d.ts +6 -6
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +24 -13
- package/dist/memory-cache.js +3 -1
- package/dist/memory-corpus-version.d.ts +19 -0
- package/dist/memory-corpus-version.js +13 -0
- package/dist/memory-corpus-version.js.map +1 -0
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.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 +21 -19
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +7 -7
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +14 -12
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +2 -2
- package/dist/operator-toolkit.js +26 -24
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +16 -14
- package/dist/{orchestrator-37Cx7yyw.d.ts → orchestrator-D83AvrPf.d.ts} +4 -4
- package/dist/orchestrator.d.ts +5 -5
- package/dist/orchestrator.js +88 -86
- package/dist/page-versioning.js +5 -1
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-C6onljHc.d.ts → pipeline-BSqGpYl1.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{qmd-J08G7MEm.d.ts → qmd-CutnpRVe.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/qmd.js +2 -2
- 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-planner-llm.d.ts +1 -1
- package/dist/recall-planner-llm.js +2 -2
- 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/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/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +2 -2
- 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/schemas.d.ts +74 -74
- 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-BFtoVosl.d.ts → semantic-consolidation-btIVRC4l.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +15 -13
- package/dist/semantic-rule-promotion.js +14 -12
- package/dist/semantic-rule-verifier.d.ts +5 -1
- package/dist/semantic-rule-verifier.js +14 -12
- 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 +9 -9
- package/dist/signal.d.ts +1 -1
- package/dist/{storage-CXjwBr69.d.ts → storage-BVv_Mqa0.d.ts} +133 -3
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +13 -11
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- 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 +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/capsule-import.js +6 -2
- package/dist/transfer/import-sqlite.js +2 -2
- package/dist/transfer/types.d.ts +66 -66
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-DpxqC8dI.d.ts → types-Cmkz7csa.d.ts} +27 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.d.ts +4 -0
- package/dist/verified-recall.js +14 -12
- package/package.json +12 -2
- package/src/binary-lifecycle/pipeline.ts +22 -0
- package/src/cli.ts +8 -0
- package/src/compounding/engine.ts +9 -1
- package/src/config.ts +14 -0
- package/src/consolidation-undo.ts +8 -0
- package/src/curation/index.ts +9 -0
- package/src/in-flight-reads.ts +63 -0
- package/src/maintenance/memory-governance.ts +6 -0
- package/src/memory-cache-hot.test.ts +131 -0
- package/src/memory-cache.ts +146 -22
- package/src/memory-corpus-version.ts +45 -0
- package/src/namespaces/storage.ts +20 -1
- package/src/operator-toolkit.ts +7 -1
- package/src/orchestration/recall-internal.ts +6 -3
- package/src/orchestrator.ts +25 -1
- package/src/page-versioning.ts +14 -1
- package/src/provenance-frontmatter.test.ts +6 -0
- package/src/review/index.ts +16 -8
- package/src/semantic-rule-promotion.ts +9 -1
- package/src/semantic-rule-verifier.ts +19 -6
- package/src/spaces/index.ts +10 -0
- package/src/storage/memory-read-store.ts +9 -2
- package/src/storage-contract/cache-coherence.test.ts +242 -0
- package/src/storage-contract/namespace-routing.test.ts +26 -1
- package/src/storage.ts +513 -31
- package/src/transfer/capsule-cache-coherence.test.ts +107 -0
- package/src/transfer/capsule-import.ts +8 -0
- package/src/transfer/capsule-merge.ts +7 -0
- package/src/types.ts +27 -0
- package/src/verified-recall.ts +20 -6
- package/dist/capsule-merge-GK5E647P.js.map +0 -1
- package/dist/chunk-74MJH7I3.js.map +0 -1
- package/dist/chunk-AD2KK5MT.js.map +0 -1
- package/dist/chunk-AWJ2FHCF.js.map +0 -1
- package/dist/chunk-EJCVMPIM.js.map +0 -1
- package/dist/chunk-GL3SMLMZ.js.map +0 -1
- package/dist/chunk-JO5AT6QT.js.map +0 -1
- package/dist/chunk-KTOH7EJE.js.map +0 -1
- package/dist/chunk-M5QKGHCR.js.map +0 -1
- package/dist/chunk-Q6JPMCPO.js.map +0 -1
- package/dist/chunk-R2SJDIPO.js.map +0 -1
- package/dist/chunk-TVRPRFUB.js.map +0 -1
- package/dist/chunk-UVIQHSS7.js.map +0 -1
- package/dist/chunk-VF4XKTX3.js.map +0 -1
- package/dist/chunk-ZUFJ7ZTR.js.map +0 -1
- /package/dist/{auto-sync-676N6N6Y.js.map → auto-sync-AAMTVZMK.js.map} +0 -0
- /package/dist/{chunk-TZJVTH3F.js.map → chunk-27VEKQQA.js.map} +0 -0
- /package/dist/{chunk-7XH7VJN4.js.map → chunk-5S7Z5SHA.js.map} +0 -0
- /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
- /package/dist/{chunk-3F4N4WDH.js.map → chunk-AHLPZ2SF.js.map} +0 -0
- /package/dist/{chunk-AH3M6F4X.js.map → chunk-CDGGQGUU.js.map} +0 -0
- /package/dist/{chunk-ZHKD4EZM.js.map → chunk-CK6RI52P.js.map} +0 -0
- /package/dist/{chunk-6C35R7P4.js.map → chunk-DJCKXI4M.js.map} +0 -0
- /package/dist/{chunk-NMMKRVUF.js.map → chunk-EIKBKQ6L.js.map} +0 -0
- /package/dist/{chunk-O3BZ6PFY.js.map → chunk-F3FC7SMO.js.map} +0 -0
- /package/dist/{chunk-ZW6OKHVX.js.map → chunk-FKCJH7KP.js.map} +0 -0
- /package/dist/{chunk-DQPPRXFO.js.map → chunk-HQ7QZJM5.js.map} +0 -0
- /package/dist/{chunk-UYZUJ4EB.js.map → chunk-I2THZUAF.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-KIPLG7S7.js.map → chunk-JKLJ6A7W.js.map} +0 -0
- /package/dist/{chunk-HXDKC3BI.js.map → chunk-JU3GHO6J.js.map} +0 -0
- /package/dist/{chunk-SYNYI4ZM.js.map → chunk-L5HJQC36.js.map} +0 -0
- /package/dist/{chunk-VXMWDXIJ.js.map → chunk-LC7OODWZ.js.map} +0 -0
- /package/dist/{chunk-CNWC274T.js.map → chunk-MLT5EG6K.js.map} +0 -0
- /package/dist/{chunk-PKGWJFNR.js.map → chunk-OVMS3DCB.js.map} +0 -0
- /package/dist/{chunk-57INMZ6F.js.map → chunk-POUD5BLV.js.map} +0 -0
- /package/dist/{chunk-LRGSLV7M.js.map → chunk-PYHOAXTI.js.map} +0 -0
- /package/dist/{chunk-WKE4VXSZ.js.map → chunk-QKVX4Y6D.js.map} +0 -0
- /package/dist/{chunk-FXGC5UUH.js.map → chunk-RT7IP3D3.js.map} +0 -0
- /package/dist/{chunk-CHVU4RE5.js.map → chunk-SKXBOZDF.js.map} +0 -0
- /package/dist/{chunk-GKCCHHZK.js.map → chunk-UXKMMNJD.js.map} +0 -0
- /package/dist/{chunk-XFTPUXCE.js.map → chunk-UXWGPODH.js.map} +0 -0
- /package/dist/{chunk-2FSHROYK.js.map → chunk-V53GJUSL.js.map} +0 -0
- /package/dist/{chunk-LKT755LP.js.map → chunk-VA4WSW54.js.map} +0 -0
- /package/dist/{chunk-FYKIEOG6.js.map → chunk-VCFADTFS.js.map} +0 -0
- /package/dist/{chunk-T7VNN3ZM.js.map → chunk-XVLEGMJI.js.map} +0 -0
- /package/dist/{chunk-CRFTLUWT.js.map → chunk-Y5U35ZVS.js.map} +0 -0
- /package/dist/{chunk-UHGHTOR5.js.map → chunk-YGAOLHKN.js.map} +0 -0
- /package/dist/{chunk-QDCJNRKK.js.map → chunk-YXOAQAH2.js.map} +0 -0
- /package/dist/{forget-KHF7A44H.js.map → forget-CQCLB5LB.js.map} +0 -0
package/dist/verified-recall.js
CHANGED
|
@@ -1,38 +1,40 @@
|
|
|
1
1
|
import {
|
|
2
2
|
compareVerifiedEpisodeResults,
|
|
3
3
|
searchVerifiedEpisodes
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KPXAJ77O.js";
|
|
5
5
|
import "./chunk-2A3OXAP2.js";
|
|
6
6
|
import "./chunk-ZBJMUXZH.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-PV7E2FGY.js";
|
|
8
8
|
import "./chunk-B3ABVQ36.js";
|
|
9
9
|
import "./chunk-L2B3EE7B.js";
|
|
10
10
|
import "./chunk-5UZXUTVO.js";
|
|
11
11
|
import "./chunk-VSMRDBFT.js";
|
|
12
|
+
import "./chunk-LTJAMRGI.js";
|
|
12
13
|
import "./chunk-EHK6KZHK.js";
|
|
13
14
|
import "./chunk-6CIAGZ6X.js";
|
|
14
15
|
import "./chunk-J6A3CX5N.js";
|
|
15
16
|
import "./chunk-4KJLYTLS.js";
|
|
16
17
|
import "./chunk-SVOZFLIQ.js";
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-JO5AT6QT.js";
|
|
19
|
-
import "./chunk-RHOZ5LLO.js";
|
|
20
|
-
import "./chunk-RL6NEVXT.js";
|
|
21
|
-
import "./chunk-AWJ2FHCF.js";
|
|
22
|
-
import "./chunk-42JKGUFJ.js";
|
|
18
|
+
import "./chunk-3ZVFLMFQ.js";
|
|
23
19
|
import "./chunk-RULE4VG5.js";
|
|
24
20
|
import "./chunk-SCU65EZI.js";
|
|
21
|
+
import "./chunk-RHOZ5LLO.js";
|
|
22
|
+
import "./chunk-RL6NEVXT.js";
|
|
25
23
|
import "./chunk-DM2T26WE.js";
|
|
26
24
|
import "./chunk-LDXUBPMO.js";
|
|
27
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-VA4WSW54.js";
|
|
28
26
|
import "./chunk-AAD2ZS6P.js";
|
|
29
27
|
import "./chunk-G7D6GZ5J.js";
|
|
30
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-VZ5OJE4X.js";
|
|
29
|
+
import "./chunk-OKUEZOGW.js";
|
|
30
|
+
import "./chunk-X47LWMKA.js";
|
|
31
|
+
import "./chunk-42JKGUFJ.js";
|
|
32
|
+
import "./chunk-PDJTHRAW.js";
|
|
31
33
|
import "./chunk-W5H6ZRPT.js";
|
|
32
|
-
import "./chunk-
|
|
34
|
+
import "./chunk-UXKMMNJD.js";
|
|
33
35
|
import "./chunk-K2ZLHESQ.js";
|
|
34
|
-
import "./chunk-L2EXJQJP.js";
|
|
35
36
|
import "./chunk-VFSP73LP.js";
|
|
37
|
+
import "./chunk-L2EXJQJP.js";
|
|
36
38
|
import "./chunk-RGMVMVMF.js";
|
|
37
39
|
import "./chunk-N7RWREIQ.js";
|
|
38
40
|
import "./chunk-OEHCMALU.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/core",
|
|
3
|
-
"version": "9.7.
|
|
3
|
+
"version": "9.7.9",
|
|
4
4
|
"description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -1090,6 +1090,16 @@
|
|
|
1090
1090
|
"remnic-source": "./src/importance.ts",
|
|
1091
1091
|
"import": "./dist/importance.js"
|
|
1092
1092
|
},
|
|
1093
|
+
"./in-flight-reads": {
|
|
1094
|
+
"types": "./dist/in-flight-reads.d.ts",
|
|
1095
|
+
"remnic-source": "./src/in-flight-reads.ts",
|
|
1096
|
+
"import": "./dist/in-flight-reads.js"
|
|
1097
|
+
},
|
|
1098
|
+
"./in-flight-reads.js": {
|
|
1099
|
+
"types": "./dist/in-flight-reads.d.ts",
|
|
1100
|
+
"remnic-source": "./src/in-flight-reads.ts",
|
|
1101
|
+
"import": "./dist/in-flight-reads.js"
|
|
1102
|
+
},
|
|
1093
1103
|
"./index": {
|
|
1094
1104
|
"types": "./dist/index.d.ts",
|
|
1095
1105
|
"remnic-source": "./src/index.ts",
|
|
@@ -3000,7 +3010,7 @@
|
|
|
3000
3010
|
"core"
|
|
3001
3011
|
],
|
|
3002
3012
|
"peerDependencies": {
|
|
3003
|
-
"@remnic/coding-graph": "^9.7.
|
|
3013
|
+
"@remnic/coding-graph": "^9.7.9"
|
|
3004
3014
|
},
|
|
3005
3015
|
"peerDependenciesMeta": {
|
|
3006
3016
|
"@remnic/coding-graph": {
|
|
@@ -18,6 +18,21 @@ import type {
|
|
|
18
18
|
import type { BinaryStorageBackend } from "./backend.js";
|
|
19
19
|
import { readManifest, writeManifest } from "./manifest.js";
|
|
20
20
|
import { scanForBinaries } from "./scanner.js";
|
|
21
|
+
import { bumpMemoryCorpusVersionForDir } from "../memory-corpus-version.js";
|
|
22
|
+
import { RECALL_FALLBACK_DIRS } from "../utils/category-dir.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* True when `mdPath` is an active recall-corpus memory file under `memoryDir`
|
|
26
|
+
* (a top-level RECALL_FALLBACK_DIRS category), so a redirect rewrite of it must
|
|
27
|
+
* bump the corpus sentinel to self-heal a warm hot-memories cache (#1902).
|
|
28
|
+
* entities/, artifacts/, and other non-recall paths need no bump.
|
|
29
|
+
*/
|
|
30
|
+
function isRecallCorpusMarkdown(mdPath: string, memoryDir: string): boolean {
|
|
31
|
+
const rel = path.relative(memoryDir, mdPath);
|
|
32
|
+
if (rel.startsWith("..") || path.isAbsolute(rel)) return false;
|
|
33
|
+
const top = rel.split(path.sep)[0];
|
|
34
|
+
return (RECALL_FALLBACK_DIRS as readonly string[]).includes(top);
|
|
35
|
+
}
|
|
21
36
|
|
|
22
37
|
/** Minimal logger interface so we don't depend on the full logger module. */
|
|
23
38
|
interface PipelineLogger {
|
|
@@ -305,6 +320,13 @@ async function stageRedirect(
|
|
|
305
320
|
for (const update of updates) {
|
|
306
321
|
try {
|
|
307
322
|
await writeMarkdownFile(update.mdPath, update.content);
|
|
323
|
+
// The redirect rewrote an on-disk memory file out-of-band (not through a
|
|
324
|
+
// StorageManager mutation). Bump the corpus sentinel per write so a warm
|
|
325
|
+
// hot-memories cache rescans — mid-batch too, never serving pre-redirect
|
|
326
|
+
// content (#1902). Only recall-corpus files affect that cache.
|
|
327
|
+
if (isRecallCorpusMarkdown(update.mdPath, memoryDir)) {
|
|
328
|
+
bumpMemoryCorpusVersionForDir(memoryDir);
|
|
329
|
+
}
|
|
308
330
|
} catch (err) {
|
|
309
331
|
writeFailCount++;
|
|
310
332
|
const msg = `redirect write failed for ${update.mdPath}: ${err instanceof Error ? err.message : String(err)}`;
|
package/src/cli.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { resolveNamespaceCapabilities,
|
|
|
10
10
|
resolveIdentityContinuityCapabilities,
|
|
11
11
|
resolveSecurityCapabilities, resolveEvalCapabilities, resolveConsolidationCapabilities, resolveRecallAuxiliaryCapabilities } from "./capabilities.js";
|
|
12
12
|
import { ThreadingManager } from "./threading.js";
|
|
13
|
+
import { bumpMemoryCorpusVersionForDir } from "./memory-corpus-version.js";
|
|
13
14
|
import { utcDayRange } from "./transcript.js";
|
|
14
15
|
import { runWearablesCliCommand } from "./wearables/cli.js";
|
|
15
16
|
import { registerResearchStatusCommands } from "./cli/research-status-commands.js";
|
|
@@ -7495,6 +7496,11 @@ export function registerCli(
|
|
|
7495
7496
|
try {
|
|
7496
7497
|
await unlink(filePath);
|
|
7497
7498
|
deleted += 1;
|
|
7499
|
+
// Per-delete corpus bump (Cursor Medium, #1902): dedupe removes
|
|
7500
|
+
// active memory files directly (bypassing StorageManager), so bump
|
|
7501
|
+
// each delete to keep a same-process or peer readAllMemories from
|
|
7502
|
+
// recalling a duplicate that was already removed mid-batch.
|
|
7503
|
+
bumpMemoryCorpusVersionForDir(memoryDir);
|
|
7498
7504
|
} catch (err) {
|
|
7499
7505
|
console.log(` failed to delete ${filePath}: ${String(err)}`);
|
|
7500
7506
|
}
|
|
@@ -7556,6 +7562,8 @@ export function registerCli(
|
|
|
7556
7562
|
try {
|
|
7557
7563
|
await unlink(filePath);
|
|
7558
7564
|
deleted += 1;
|
|
7565
|
+
// Per-delete corpus bump (Cursor Medium, #1902) — see dedupe-exact.
|
|
7566
|
+
bumpMemoryCorpusVersionForDir(memoryDir);
|
|
7559
7567
|
} catch (err) {
|
|
7560
7568
|
console.log(` failed to delete ${filePath}: ${String(err)}`);
|
|
7561
7569
|
}
|
|
@@ -321,7 +321,15 @@ function normalizePromotionWhitespace(value: string): string {
|
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
function stripTrailingPromotionPunctuation(value: string): string {
|
|
324
|
-
|
|
324
|
+
// Linear trailing-punctuation strip (no `/[,:;]+$/` — CodeQL flags that as a
|
|
325
|
+
// polynomial-backtracking ReDoS on long runs of ',;:'). Walk back once, O(n).
|
|
326
|
+
let end = value.length;
|
|
327
|
+
while (end > 0) {
|
|
328
|
+
const ch = value[end - 1];
|
|
329
|
+
if (ch === "," || ch === ":" || ch === ";") end--;
|
|
330
|
+
else break;
|
|
331
|
+
}
|
|
332
|
+
return value.slice(0, end).trim();
|
|
325
333
|
}
|
|
326
334
|
|
|
327
335
|
function extractExplicitIfThenRule(value: string): string | null {
|
package/src/config.ts
CHANGED
|
@@ -2106,6 +2106,20 @@ export function parseConfig(
|
|
|
2106
2106
|
// opt out with recallMemoryWorthFilterEnabled=false.
|
|
2107
2107
|
recallMemoryWorthFilterEnabled:
|
|
2108
2108
|
coerceBool(cfg.recallMemoryWorthFilterEnabled) ?? true,
|
|
2109
|
+
// Hot-memories result cache (issue #1902). Default on: readAllMemories()
|
|
2110
|
+
// serves from the version-keyed in-process corpus cache. coerceBool
|
|
2111
|
+
// handles "false"/"0" string forms; set false to force disk scans.
|
|
2112
|
+
hotMemoriesCacheEnabled: coerceBool(cfg.hotMemoriesCacheEnabled) ?? true,
|
|
2113
|
+
// External-edit safety net (issue #1902): the version sentinel gives
|
|
2114
|
+
// immediate coherence for cooperating writers, but direct user/git/editor
|
|
2115
|
+
// writes to memory files (which the project supports) don't bump it. Bound
|
|
2116
|
+
// the hot cache's staleness with a TTL so such edits self-heal. Default 60s;
|
|
2117
|
+
// 0 disables the TTL (version invalidation only — max perf for pure-daemon
|
|
2118
|
+
// deployments with no external edits). coerceNumber handles string forms.
|
|
2119
|
+
hotMemoriesCacheTtlMs: (() => {
|
|
2120
|
+
const n = coerceNumber(cfg.hotMemoriesCacheTtlMs);
|
|
2121
|
+
return n !== undefined && n >= 0 ? n : 60_000;
|
|
2122
|
+
})(),
|
|
2109
2123
|
recallMemoryWorthHalfLifeMs: (() => {
|
|
2110
2124
|
const n = coerceNumber(cfg.recallMemoryWorthHalfLifeMs);
|
|
2111
2125
|
return n !== undefined && n >= 0 ? n : 0;
|
|
@@ -25,6 +25,7 @@ import { mkdir, writeFile, access, realpath, lstat } from "node:fs/promises";
|
|
|
25
25
|
import { constants as fsConstants } from "node:fs";
|
|
26
26
|
import type { StorageManager } from "./storage.js";
|
|
27
27
|
import type { VersioningConfig } from "./page-versioning.js";
|
|
28
|
+
import { bumpMemoryCorpusVersionForDir } from "./memory-corpus-version.js";
|
|
28
29
|
import { getVersion } from "./page-versioning.js";
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -646,6 +647,13 @@ export async function runConsolidationUndo(options: {
|
|
|
646
647
|
// write fails with EEXIST instead of silently overwriting the new
|
|
647
648
|
// file (PR #637 round-11 review, codex P1).
|
|
648
649
|
await writeFile(p.sourcePath, p.content, { encoding: "utf-8", flag: "wx" });
|
|
650
|
+
// Restore writes an active memory file back out-of-band (direct wx write,
|
|
651
|
+
// not a StorageManager mutation). Bump the corpus sentinel per successful
|
|
652
|
+
// restore so a warm hot-memories cache rescans — a later restore failure
|
|
653
|
+
// returns before archiveMemory() runs, so without this the already-written
|
|
654
|
+
// restores would stay invisible to recall until an unrelated mutation or
|
|
655
|
+
// restart (esp. with hotMemoriesCacheTtlMs: 0). Issue #1902, Codex Medium.
|
|
656
|
+
bumpMemoryCorpusVersionForDir(memoryDir);
|
|
649
657
|
result.restores.push({
|
|
650
658
|
entry: p.entry,
|
|
651
659
|
sourcePath: p.sourcePath,
|
package/src/curation/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import fs from "node:fs";
|
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import crypto from "node:crypto";
|
|
11
11
|
import { getCategoryDir, ALL_CATEGORY_DIRS } from "../utils/category-dir.js";
|
|
12
|
+
import { bumpMemoryCorpusVersionForDir } from "../memory-corpus-version.js";
|
|
12
13
|
|
|
13
14
|
// ── Types ────────────────────────────────────────────────────────────────────
|
|
14
15
|
|
|
@@ -202,6 +203,10 @@ export async function curate(options: CurateOptions): Promise<CurateResult> {
|
|
|
202
203
|
}
|
|
203
204
|
}
|
|
204
205
|
|
|
206
|
+
// Per-statement corpus bumps happen in writeStatement (below) so a
|
|
207
|
+
// same-process readAllMemories mid-batch never serves a stale/partial corpus
|
|
208
|
+
// (Cursor Medium, #1902); no after-loop bump needed here.
|
|
209
|
+
|
|
205
210
|
return {
|
|
206
211
|
statements,
|
|
207
212
|
filesProcessed,
|
|
@@ -471,6 +476,10 @@ function writeStatement(stmt: CuratedStatement, memoryDir: string): string {
|
|
|
471
476
|
const body = `${frontmatter}\n\n${stmt.content}\n`;
|
|
472
477
|
|
|
473
478
|
fs.writeFileSync(filePath, body);
|
|
479
|
+
// Bump the corpus sentinel per write (out-of-band create) so a concurrent
|
|
480
|
+
// same-process readAllMemories rescans and sees this statement immediately,
|
|
481
|
+
// never a stale/partial corpus mid-batch (Cursor Medium, #1902).
|
|
482
|
+
bumpMemoryCorpusVersionForDir(memoryDir);
|
|
474
483
|
return filePath;
|
|
475
484
|
}
|
|
476
485
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { MemoryFile } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* In-flight readAllMemories() dedup registry (issue #1902).
|
|
5
|
+
*
|
|
6
|
+
* NOT a cache layer — it holds transient per-(directory, secure-store key) scan
|
|
7
|
+
* promises so temporally-overlapping reads collapse onto ONE disk scan; the slot
|
|
8
|
+
* is deleted when the promise settles. It lives in its own module (not
|
|
9
|
+
* memory-cache.ts) so it is not swept by the ALL_CACHE_LAYERS invalidation
|
|
10
|
+
* contract, yet remains importable by both StorageManager and the out-of-band
|
|
11
|
+
* corpus-bump helper (memory-corpus-version.ts).
|
|
12
|
+
*
|
|
13
|
+
* Keyed by baseDir AND secure-store key identity (Codex P1 / Cursor Medium):
|
|
14
|
+
* an unlocked manager's decrypted scan must NOT be handed to a locked or
|
|
15
|
+
* differently-keyed manager for the same dir — that would bypass the keyId
|
|
16
|
+
* isolation getCachedMemories enforces. Locked/plaintext stores use keyId "".
|
|
17
|
+
*/
|
|
18
|
+
const inFlightReadsByKey = new Map<string, Promise<MemoryFile[]>>();
|
|
19
|
+
|
|
20
|
+
const DIR_SEP = "\u0000";
|
|
21
|
+
|
|
22
|
+
function composeKey(baseDir: string, keyId: string): string {
|
|
23
|
+
return `${baseDir}${DIR_SEP}${keyId}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getInFlightRead(baseDir: string, keyId = ""): Promise<MemoryFile[]> | undefined {
|
|
27
|
+
return inFlightReadsByKey.get(composeKey(baseDir, keyId));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function setInFlightRead(baseDir: string, keyId: string, read: Promise<MemoryFile[]>): void {
|
|
31
|
+
inFlightReadsByKey.set(composeKey(baseDir, keyId), read);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Delete the in-flight slot for one (baseDir, keyId). When `expected` is given,
|
|
36
|
+
* only deletes if the slot still holds that exact promise (owner-only clear).
|
|
37
|
+
*/
|
|
38
|
+
export function deleteInFlightRead(
|
|
39
|
+
baseDir: string,
|
|
40
|
+
keyId = "",
|
|
41
|
+
expected?: Promise<MemoryFile[]>,
|
|
42
|
+
): void {
|
|
43
|
+
const key = composeKey(baseDir, keyId);
|
|
44
|
+
if (expected === undefined || inFlightReadsByKey.get(key) === expected) {
|
|
45
|
+
inFlightReadsByKey.delete(key);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Drop EVERY in-flight slot for `baseDir` across all secure-store identities.
|
|
51
|
+
* Used by mutations / invalidation / out-of-band corpus bumps: after the corpus
|
|
52
|
+
* changes, no reader of any key identity may attach to a pre-mutation scan.
|
|
53
|
+
*/
|
|
54
|
+
export function deleteInFlightReadsForDir(baseDir: string): void {
|
|
55
|
+
const prefix = `${baseDir}${DIR_SEP}`;
|
|
56
|
+
for (const key of inFlightReadsByKey.keys()) {
|
|
57
|
+
if (key.startsWith(prefix)) inFlightReadsByKey.delete(key);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function clearInFlightReads(): void {
|
|
62
|
+
inFlightReadsByKey.clear();
|
|
63
|
+
}
|
|
@@ -4,6 +4,7 @@ import { StorageManager } from "../storage.js";
|
|
|
4
4
|
import { decideLifecycleTransition } from "../lifecycle.js";
|
|
5
5
|
import type { MemoryFile, MemoryStatus } from "../types.js";
|
|
6
6
|
import { RECALL_FALLBACK_DIRS } from "../utils/category-dir.js";
|
|
7
|
+
import { bumpMemoryCorpusVersionForDir } from "../memory-corpus-version.js";
|
|
7
8
|
import { assertPathInsideRoot } from "../utils/path-containment.js";
|
|
8
9
|
|
|
9
10
|
export type MemoryGovernanceMode = "shadow" | "apply";
|
|
@@ -1015,6 +1016,11 @@ export async function restoreMemoryGovernanceRun(
|
|
|
1015
1016
|
await mkdir(path.dirname(entry.originalPath), { recursive: true });
|
|
1016
1017
|
await writeFile(entry.originalPath, entry.beforeRaw, "utf-8");
|
|
1017
1018
|
restoredActions += 1;
|
|
1019
|
+
// Restore writes/removes memory files directly (out-of-band — not through a
|
|
1020
|
+
// StorageManager mutation). Bump the corpus sentinel PER entry so a
|
|
1021
|
+
// same-process or peer readAllMemories rescans mid-batch and never serves a
|
|
1022
|
+
// partially-restored corpus (Cursor Medium, #1902).
|
|
1023
|
+
bumpMemoryCorpusVersionForDir(options.memoryDir);
|
|
1018
1024
|
}
|
|
1019
1025
|
|
|
1020
1026
|
return {
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue #1902 — unit tests for the hot-memories result cache layer.
|
|
3
|
+
*
|
|
4
|
+
* These pin the low-level cache contract that StorageManager.readAllMemories()
|
|
5
|
+
* relies on: version-keyed round-trip, the version-0 and version-mismatch null
|
|
6
|
+
* guards, in-place patch-on-write / patch-on-delete, and the two invalidation
|
|
7
|
+
* shapes (wholesale drop vs derived/global-only keep).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import assert from "node:assert/strict";
|
|
11
|
+
import test from "node:test";
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
clearMemoryCache,
|
|
15
|
+
getCachedMemories,
|
|
16
|
+
invalidateAllForDir,
|
|
17
|
+
invalidateDerivedAndGlobalForDir,
|
|
18
|
+
setCachedMemories,
|
|
19
|
+
updateCacheOnDelete,
|
|
20
|
+
updateCacheOnWrite,
|
|
21
|
+
} from "./memory-cache.js";
|
|
22
|
+
import type { MemoryFile } from "./types.js";
|
|
23
|
+
|
|
24
|
+
function mem(p: string, content = "x"): MemoryFile {
|
|
25
|
+
return {
|
|
26
|
+
path: p,
|
|
27
|
+
frontmatter: { id: p, category: "fact" },
|
|
28
|
+
content,
|
|
29
|
+
} as unknown as MemoryFile;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
test("hot cache: round-trips at a matching version", () => {
|
|
33
|
+
const dir = "/tmp/remnic-hot-unit-a";
|
|
34
|
+
clearMemoryCache();
|
|
35
|
+
setCachedMemories(dir, [mem("a.md"), mem("b.md")], 3);
|
|
36
|
+
const got = getCachedMemories(dir, 3);
|
|
37
|
+
assert.ok(got, "expected a cache hit at the matching version");
|
|
38
|
+
assert.deepEqual(got!.map((m) => m.path).sort(), ["a.md", "b.md"]);
|
|
39
|
+
clearMemoryCache();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("hot cache: version 0 always misses (fresh/test dirs)", () => {
|
|
43
|
+
const dir = "/tmp/remnic-hot-unit-b";
|
|
44
|
+
clearMemoryCache();
|
|
45
|
+
setCachedMemories(dir, [mem("a.md")], 0);
|
|
46
|
+
assert.equal(getCachedMemories(dir, 0), null, "version 0 must never serve a cache hit");
|
|
47
|
+
clearMemoryCache();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("hot cache: version mismatch misses (never serves stale)", () => {
|
|
51
|
+
const dir = "/tmp/remnic-hot-unit-c";
|
|
52
|
+
clearMemoryCache();
|
|
53
|
+
setCachedMemories(dir, [mem("a.md")], 5);
|
|
54
|
+
assert.ok(getCachedMemories(dir, 5), "same version hits");
|
|
55
|
+
assert.equal(getCachedMemories(dir, 6), null, "a bumped version must miss");
|
|
56
|
+
clearMemoryCache();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("hot cache: updateCacheOnWrite / updateCacheOnDelete mutate the entry in place", () => {
|
|
60
|
+
const dir = "/tmp/remnic-hot-unit-d";
|
|
61
|
+
clearMemoryCache();
|
|
62
|
+
setCachedMemories(dir, [mem("a.md")], 2);
|
|
63
|
+
updateCacheOnWrite(dir, mem("b.md", "new"));
|
|
64
|
+
const afterWrite = getCachedMemories(dir, 2);
|
|
65
|
+
assert.deepEqual(afterWrite!.map((m) => m.path).sort(), ["a.md", "b.md"], "write adds in place");
|
|
66
|
+
updateCacheOnWrite(dir, mem("a.md", "updated"));
|
|
67
|
+
assert.equal(
|
|
68
|
+
getCachedMemories(dir, 2)!.find((m) => m.path === "a.md")!.content,
|
|
69
|
+
"updated",
|
|
70
|
+
"write to an existing path replaces in place",
|
|
71
|
+
);
|
|
72
|
+
updateCacheOnDelete(dir, "a.md");
|
|
73
|
+
assert.deepEqual(getCachedMemories(dir, 2)!.map((m) => m.path), ["b.md"], "delete removes in place");
|
|
74
|
+
clearMemoryCache();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("hot cache: wholesale invalidateAllForDir drops the hot layer; invalidateDerivedAndGlobalForDir keeps it", () => {
|
|
78
|
+
const dir = "/tmp/remnic-hot-unit-e";
|
|
79
|
+
clearMemoryCache();
|
|
80
|
+
setCachedMemories(dir, [mem("a.md")], 4);
|
|
81
|
+
invalidateDerivedAndGlobalForDir(dir);
|
|
82
|
+
assert.ok(
|
|
83
|
+
getCachedMemories(dir, 4),
|
|
84
|
+
"invalidateDerivedAndGlobalForDir must NOT drop the hot layer (patch-on-write keeps it warm)",
|
|
85
|
+
);
|
|
86
|
+
invalidateAllForDir(dir);
|
|
87
|
+
assert.equal(getCachedMemories(dir, 4), null, "invalidateAllForDir must drop the hot layer");
|
|
88
|
+
clearMemoryCache();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("hot cache: keyId scopes entries — a mismatched secure-store key misses (#1902 Codex P1)", () => {
|
|
92
|
+
const dir = "/tmp/remnic-hot-unit-keyid";
|
|
93
|
+
clearMemoryCache();
|
|
94
|
+
// A keyed (unlocked encrypted) manager warms the cache with decrypted content.
|
|
95
|
+
setCachedMemories(dir, [mem("secret.md", "decrypted")], 5, "secure-store:key:1");
|
|
96
|
+
// A locked/unkeyed manager for the SAME dir must NOT read the decrypted entry.
|
|
97
|
+
assert.equal(
|
|
98
|
+
getCachedMemories(dir, 5, ""),
|
|
99
|
+
null,
|
|
100
|
+
"a manager without the matching key must miss the decrypted cache entry",
|
|
101
|
+
);
|
|
102
|
+
// A different key id also misses.
|
|
103
|
+
assert.equal(getCachedMemories(dir, 5, "secure-store:key:2"), null, "a different key id misses");
|
|
104
|
+
// The matching key id hits.
|
|
105
|
+
const got = getCachedMemories(dir, 5, "secure-store:key:1");
|
|
106
|
+
assert.ok(got, "the matching key id serves the cached corpus");
|
|
107
|
+
assert.deepEqual(got!.map((m) => m.path), ["secret.md"]);
|
|
108
|
+
clearMemoryCache();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("hot cache: TTL expires an entry so external edits self-heal (#1902 Codex P1)", (t) => {
|
|
112
|
+
const dir = "/tmp/remnic-hot-unit-ttl";
|
|
113
|
+
clearMemoryCache();
|
|
114
|
+
// Deterministic time control (no real timers): the entry's loadedAt is stamped
|
|
115
|
+
// from the mocked clock at set time; advancing it past the TTL forces a miss.
|
|
116
|
+
t.mock.timers.enable({ apis: ["Date"] });
|
|
117
|
+
try {
|
|
118
|
+
setCachedMemories(dir, [mem("a.md")], 9, "");
|
|
119
|
+
// ttl=0 disables the TTL: always a hit at the matching version.
|
|
120
|
+
assert.ok(getCachedMemories(dir, 9, "", 0), "ttl=0 disables expiry");
|
|
121
|
+
// Fresh entry within a generous TTL still hits.
|
|
122
|
+
assert.ok(getCachedMemories(dir, 9, "", 60_000), "fresh entry within TTL hits");
|
|
123
|
+
// Advance past the TTL: the entry is now a miss, forcing a rescan that would
|
|
124
|
+
// pick up any external filesystem edit that bypassed the version sentinel.
|
|
125
|
+
t.mock.timers.tick(120_000);
|
|
126
|
+
assert.equal(getCachedMemories(dir, 9, "", 60_000), null, "entry older than ttl is a miss");
|
|
127
|
+
} finally {
|
|
128
|
+
t.mock.timers.reset();
|
|
129
|
+
clearMemoryCache();
|
|
130
|
+
}
|
|
131
|
+
});
|