@remnic/core 9.62.1 → 9.63.0
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 +11 -11
- package/dist/access-admin-ops-surface.js +26 -26
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +11 -11
- package/dist/access-authorization-probe.js +27 -27
- package/dist/access-boundary.d.ts +11 -11
- package/dist/access-boundary.js +26 -26
- package/dist/access-cli.js +88 -86
- 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 +11 -11
- package/dist/access-extraction-force-flush.js +26 -26
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +11 -11
- package/dist/access-http-lifecycle-flush.d.ts +11 -11
- package/dist/access-http-offline-stream.d.ts +11 -11
- package/dist/access-http-query.js +26 -26
- package/dist/access-http.d.ts +12 -12
- package/dist/access-http.js +36 -36
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +26 -26
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +26 -26
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +31 -31
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-EMvicnrb.d.ts → access-namespace-preflight-yO4LMGFH.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +26 -26
- package/dist/access-observe-write-surface.d.ts +11 -11
- package/dist/access-observe-write-surface.js +26 -26
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-offline-manifest.js +2 -2
- package/dist/access-operations-batch.js +27 -27
- package/dist/access-operations.d.ts +11 -11
- package/dist/access-operations.js +30 -30
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +26 -26
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +26 -26
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +26 -26
- package/dist/{access-service-BeDYQQ62.d.ts → access-service-M4LgO141.d.ts} +7 -7
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +26 -26
- package/dist/access-surface-catalog.d.ts +11 -11
- package/dist/access-surface-catalog.js +28 -28
- 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 +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-FMWQQB3J.js → auto-sync-Z52VWMNC.js} +3 -3
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-learner.js +2 -2
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +11 -10
- 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/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-B2SxZ6LU.d.ts → catalog-CyYTf_ok.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +3 -3
- package/dist/causal-chain.js +3 -3
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +14 -14
- package/dist/causal-retrieval.js +3 -3
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/causal-trajectory.js +2 -2
- package/dist/{chunk-B2QHVLJO.js → chunk-256FBCVX.js} +22 -10
- package/dist/chunk-256FBCVX.js.map +1 -0
- package/dist/{chunk-QP2IZTUR.js → chunk-2TYIAKU5.js} +2 -2
- package/dist/{chunk-QNMNNFKD.js → chunk-347ZR6D4.js} +2 -2
- package/dist/{chunk-76YNCJ5H.js → chunk-3F3CVVDS.js} +2 -2
- package/dist/{chunk-KCFZOSR6.js → chunk-3MA7JVXN.js} +4 -4
- package/dist/{chunk-KHQ57QLJ.js → chunk-46WM6JX2.js} +7 -3
- package/dist/chunk-46WM6JX2.js.map +1 -0
- package/dist/chunk-47DU4SGJ.js +92 -0
- package/dist/chunk-47DU4SGJ.js.map +1 -0
- package/dist/{chunk-HKYNBEL4.js → chunk-4FFROSFG.js} +37 -14
- package/dist/{chunk-HKYNBEL4.js.map → chunk-4FFROSFG.js.map} +1 -1
- package/dist/{chunk-TLUSSS2F.js → chunk-4HO3542O.js} +2 -2
- package/dist/{chunk-4E67XCT2.js → chunk-4IZ2IT7D.js} +3 -3
- package/dist/{chunk-33JBK2XP.js → chunk-5F6HMNMZ.js} +2 -2
- package/dist/{chunk-5WQMORU5.js → chunk-5PFGMO33.js} +2 -2
- package/dist/{chunk-6HEM6HTQ.js → chunk-6GGTATZF.js} +2 -2
- package/dist/{chunk-UIRU3MIJ.js → chunk-7BJYTX6Q.js} +2 -2
- package/dist/{chunk-2GRLJMKJ.js → chunk-7DRSWPUV.js} +3 -3
- package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
- package/dist/{chunk-HXXGZ4KV.js → chunk-ALNZEWGN.js} +2 -2
- package/dist/{chunk-5WVUO6QT.js → chunk-AR253JBM.js} +1 -1
- package/dist/chunk-AR253JBM.js.map +1 -0
- package/dist/{chunk-67MKNKJQ.js → chunk-AYIHDC5S.js} +2 -2
- package/dist/{chunk-IXJ5U6ZL.js → chunk-BBHFAVMP.js} +8 -8
- package/dist/{chunk-IIRK5V5Z.js → chunk-BHO6RHE5.js} +3 -3
- package/dist/{chunk-WANOCU3K.js → chunk-BP6WMYLP.js} +3 -3
- package/dist/{chunk-ZJKLGS76.js → chunk-CALURYWR.js} +283 -248
- package/dist/chunk-CALURYWR.js.map +1 -0
- package/dist/{chunk-JLMH5YMU.js → chunk-CH627RRV.js} +2 -2
- package/dist/{chunk-XIABRKF6.js → chunk-CLJ5QS6J.js} +239 -47
- package/dist/chunk-CLJ5QS6J.js.map +1 -0
- package/dist/{chunk-YLHM5BQQ.js → chunk-DCUMFQYM.js} +171 -8
- package/dist/chunk-DCUMFQYM.js.map +1 -0
- package/dist/{chunk-ZBJMUXZH.js → chunk-DJ7HMNSL.js} +15 -8
- package/dist/chunk-DJ7HMNSL.js.map +1 -0
- package/dist/{chunk-WTMG5GAK.js → chunk-DROAPP6N.js} +3 -3
- package/dist/{chunk-PBH2Z2NY.js → chunk-DTLF2SLZ.js} +2 -2
- package/dist/{chunk-7JAXC526.js → chunk-EFWHCTYJ.js} +2 -2
- package/dist/{chunk-3XG4QEA2.js → chunk-FF6E6HOT.js} +39 -39
- package/dist/{chunk-NP7FLVZW.js → chunk-G2FCSILA.js} +2 -2
- package/dist/{chunk-7PVTOZR4.js → chunk-H23GIXJC.js} +2 -2
- package/dist/{chunk-WT6UL3UA.js → chunk-H7PRHUBD.js} +2 -2
- package/dist/{chunk-ETCVSZLG.js → chunk-HSBQJRV2.js} +2 -2
- package/dist/{chunk-GZRDOVQN.js → chunk-HVKMJAEF.js} +2 -2
- package/dist/{chunk-CSOYVTRX.js → chunk-IIPJKCZB.js} +3 -3
- package/dist/{chunk-E57E5SCS.js → chunk-IRLH4NM2.js} +3 -3
- package/dist/{chunk-4G45LJJP.js → chunk-IZRNVNPV.js} +2 -2
- package/dist/{chunk-YSUSUZR4.js → chunk-JCJGYNIS.js} +3 -3
- package/dist/{chunk-EU74U4GT.js → chunk-JDI7G6EA.js} +2 -2
- package/dist/{chunk-QWPAQLYV.js → chunk-JFLKSD5V.js} +2 -2
- package/dist/{chunk-KQS72GCR.js → chunk-LJOIZPJH.js} +2 -2
- package/dist/{chunk-U27G4E5G.js → chunk-LLGDVG52.js} +3 -3
- package/dist/{chunk-7N7DB4L5.js → chunk-LTJTP5YQ.js} +10 -9
- package/dist/chunk-LTJTP5YQ.js.map +1 -0
- package/dist/{chunk-XL3TATMJ.js → chunk-OQIRBGUU.js} +21 -12
- package/dist/chunk-OQIRBGUU.js.map +1 -0
- package/dist/{chunk-JGW2EUCQ.js → chunk-PMRUMGK6.js} +2 -2
- package/dist/{chunk-3G6YU5YD.js → chunk-PSNN25DW.js} +2 -2
- package/dist/{chunk-LRGSLV7M.js → chunk-PYHOAXTI.js} +4 -4
- package/dist/{chunk-75U2FR7U.js → chunk-QCI73Z7C.js} +2 -2
- package/dist/{chunk-EHMMRZOZ.js → chunk-QICOU4RY.js} +2 -2
- package/dist/{chunk-K4WIUTNH.js → chunk-RFH7U5LT.js} +2 -2
- package/dist/{chunk-4SGDYYWV.js → chunk-RPKJHYVE.js} +2 -2
- package/dist/{chunk-BHO3IVAN.js → chunk-RYST72N5.js} +12 -1
- package/dist/chunk-RYST72N5.js.map +1 -0
- package/dist/chunk-T3GIETKV.js +152 -0
- package/dist/chunk-T3GIETKV.js.map +1 -0
- package/dist/{chunk-DYDACAK2.js → chunk-TGSMU3F2.js} +3 -3
- package/dist/{chunk-MJFDJTDC.js → chunk-TIRJV2LW.js} +2 -2
- package/dist/{chunk-QRA3XVJX.js → chunk-UDTME32W.js} +2 -2
- package/dist/{chunk-LAM6UDFV.js → chunk-WMOJIOIG.js} +2 -2
- package/dist/{chunk-LLLY5IBK.js → chunk-WR2YKUIW.js} +2 -2
- package/dist/{chunk-KYI3CM42.js → chunk-X6E7TT3A.js} +2 -2
- package/dist/{chunk-QN7XQEIT.js → chunk-YIIC5IDU.js} +2 -2
- package/dist/{chunk-JDJOAL4B.js → chunk-YSR3DXGC.js} +2 -2
- package/dist/{chunk-LBJBNWS2.js → chunk-YTHQHH5U.js} +2 -2
- package/dist/{chunk-JF6YSHJM.js → chunk-ZPGHA7EO.js} +12 -12
- package/dist/{chunk-VUDALPI5.js → chunk-ZQKXRKMR.js} +19 -5
- package/dist/chunk-ZQKXRKMR.js.map +1 -0
- package/dist/{chunk-YG56A6XY.js → chunk-ZS4JADYY.js} +3 -3
- package/dist/{cli-DB_uakTc.d.ts → cli-Bw9z-KqX.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +60 -60
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/coding/pre-action-gate.js +3 -3
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +11 -10
- 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 +11 -10
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +11 -10
- 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/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +13 -12
- 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/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +13 -12
- 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-DcOVpK3y.d.ts → dependency-propagation-delivery-BxhvAppj.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer-wiring.js +3 -3
- package/dist/direct-answer.d.ts +1 -1
- package/dist/direct-answer.js +2 -2
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +11 -10
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +92 -0
- package/dist/episodic-context.js +16 -0
- package/dist/episodic-context.js.map +1 -0
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/external-wiki-access.d.ts +11 -11
- package/dist/external-wiki-access.js +27 -27
- 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 +11 -11
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- 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-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-normalization.js +2 -2
- 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 +14 -14
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{forget-5TWK7CZT.js → forget-SZ2BXDGF.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-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-construction.js +2 -2
- package/dist/harmonic-retrieval.js +2 -2
- 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 +21 -21
- package/dist/index.js +100 -98
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +8 -2
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +9 -9
- 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 +11 -10
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +11 -10
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +12 -11
- package/dist/{maintenance-5c1olVtB.d.ts → maintenance-uJb74j64.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -11
- 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-store.d.ts +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 +12 -11
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +6 -5
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +11 -10
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +14 -13
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +19 -18
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +16 -15
- package/dist/{orchestrator-HPuY6I4i.d.ts → orchestrator-CFi-5JSR.d.ts} +23 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +88 -86
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CvVe1Q2_.d.ts → pipeline-BdF3ferY.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/policy-runtime.js +3 -3
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{public-http-D0JKFkyf.d.ts → public-http-DK-QwaBu.d.ts} +1 -1
- package/dist/{qmd-Bd0Tp76_.d.ts → qmd-D_62bYNl.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-query-policy.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-tokenization.d.ts +3 -1
- package/dist/recall-tokenization.js +5 -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 +1 -1
- package/dist/reconcile/manifest.d.ts +10 -1
- package/dist/reconcile/manifest.js +1 -1
- package/dist/reconcile/plan.d.ts +1 -1
- 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 +4 -4
- 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/{scope-profiles-ClLtm9gK.d.ts → scope-profiles-CeMv7pP0.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 +5 -4
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +9 -8
- package/dist/search/lancedb-backend.d.ts +14 -1
- package/dist/search/lancedb-backend.js +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 +22 -1
- package/dist/search/orama-backend.js +2 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-B1EkeEDj.d.ts → semantic-consolidation-B-85brYj.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +12 -12
- package/dist/semantic-rule-promotion.js +11 -10
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +11 -11
- package/dist/{service-Cf3ANQj9.d.ts → service-CoO0HA2E.d.ts} +2 -2
- 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 +11 -10
- package/dist/{storage-DS2O_6Qt.d.ts → storage-BVAVitkO.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +10 -9
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +14 -14
- package/dist/support-passport/index.js +29 -29
- 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/import-sqlite.js +2 -2
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/trust-zones.js +2 -2
- package/dist/{types-BOANGhCJ.d.ts → types-DWHOxlZP.d.ts} +3 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/user-message-cleaning.d.ts +23 -0
- package/dist/user-message-cleaning.js +10 -0
- package/dist/user-message-cleaning.js.map +1 -0
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +11 -11
- package/dist/work-product-ledger.js +2 -2
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +12 -2
- package/src/access-service-offline-file-content.test.ts +1 -0
- package/src/config.ts +11 -0
- package/src/episodic-context-recall.integration.test.ts +169 -0
- package/src/episodic-context.test.ts +266 -0
- package/src/episodic-context.ts +274 -0
- package/src/lcm/engine.ts +18 -1
- package/src/lifecycle/tombstones.test.ts +134 -0
- package/src/lifecycle/tombstones.ts +29 -2
- package/src/orchestration/episodic-context-section.ts +255 -0
- package/src/orchestration/recall-internal-deps.ts +2 -0
- package/src/orchestration/recall-internal.ts +40 -25
- package/src/orchestration/recall-result-formatter.ts +37 -0
- package/src/recall-tokenization.ts +14 -8
- package/src/reconcile/manifest.test.ts +133 -4
- package/src/reconcile/manifest.ts +43 -7
- package/src/search/factory.ts +1 -0
- package/src/search/lancedb-backend.ts +24 -16
- package/src/search/orama-backend.test.ts +208 -1
- package/src/search/orama-backend.ts +133 -18
- package/src/search/orama-cjk-tokenizer.test.ts +108 -0
- package/src/search/orama-cjk-tokenizer.ts +143 -0
- package/src/storage/tombstone-migration-sources.test.ts +116 -0
- package/src/storage/tombstone-migration-sources.ts +90 -0
- package/src/storage.ts +13 -34
- package/src/types.ts +3 -3
- package/src/user-message-cleaning.ts +139 -0
- package/dist/chunk-5WVUO6QT.js.map +0 -1
- package/dist/chunk-7N7DB4L5.js.map +0 -1
- package/dist/chunk-B2QHVLJO.js.map +0 -1
- package/dist/chunk-BHO3IVAN.js.map +0 -1
- package/dist/chunk-KHQ57QLJ.js.map +0 -1
- package/dist/chunk-VUDALPI5.js.map +0 -1
- package/dist/chunk-XIABRKF6.js.map +0 -1
- package/dist/chunk-XL3TATMJ.js.map +0 -1
- package/dist/chunk-YLHM5BQQ.js.map +0 -1
- package/dist/chunk-ZBJMUXZH.js.map +0 -1
- package/dist/chunk-ZJKLGS76.js.map +0 -1
- /package/dist/{auto-sync-FMWQQB3J.js.map → auto-sync-Z52VWMNC.js.map} +0 -0
- /package/dist/{chunk-QP2IZTUR.js.map → chunk-2TYIAKU5.js.map} +0 -0
- /package/dist/{chunk-QNMNNFKD.js.map → chunk-347ZR6D4.js.map} +0 -0
- /package/dist/{chunk-76YNCJ5H.js.map → chunk-3F3CVVDS.js.map} +0 -0
- /package/dist/{chunk-KCFZOSR6.js.map → chunk-3MA7JVXN.js.map} +0 -0
- /package/dist/{chunk-TLUSSS2F.js.map → chunk-4HO3542O.js.map} +0 -0
- /package/dist/{chunk-4E67XCT2.js.map → chunk-4IZ2IT7D.js.map} +0 -0
- /package/dist/{chunk-33JBK2XP.js.map → chunk-5F6HMNMZ.js.map} +0 -0
- /package/dist/{chunk-5WQMORU5.js.map → chunk-5PFGMO33.js.map} +0 -0
- /package/dist/{chunk-6HEM6HTQ.js.map → chunk-6GGTATZF.js.map} +0 -0
- /package/dist/{chunk-UIRU3MIJ.js.map → chunk-7BJYTX6Q.js.map} +0 -0
- /package/dist/{chunk-2GRLJMKJ.js.map → chunk-7DRSWPUV.js.map} +0 -0
- /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
- /package/dist/{chunk-HXXGZ4KV.js.map → chunk-ALNZEWGN.js.map} +0 -0
- /package/dist/{chunk-67MKNKJQ.js.map → chunk-AYIHDC5S.js.map} +0 -0
- /package/dist/{chunk-IXJ5U6ZL.js.map → chunk-BBHFAVMP.js.map} +0 -0
- /package/dist/{chunk-IIRK5V5Z.js.map → chunk-BHO6RHE5.js.map} +0 -0
- /package/dist/{chunk-WANOCU3K.js.map → chunk-BP6WMYLP.js.map} +0 -0
- /package/dist/{chunk-JLMH5YMU.js.map → chunk-CH627RRV.js.map} +0 -0
- /package/dist/{chunk-WTMG5GAK.js.map → chunk-DROAPP6N.js.map} +0 -0
- /package/dist/{chunk-PBH2Z2NY.js.map → chunk-DTLF2SLZ.js.map} +0 -0
- /package/dist/{chunk-7JAXC526.js.map → chunk-EFWHCTYJ.js.map} +0 -0
- /package/dist/{chunk-3XG4QEA2.js.map → chunk-FF6E6HOT.js.map} +0 -0
- /package/dist/{chunk-NP7FLVZW.js.map → chunk-G2FCSILA.js.map} +0 -0
- /package/dist/{chunk-7PVTOZR4.js.map → chunk-H23GIXJC.js.map} +0 -0
- /package/dist/{chunk-WT6UL3UA.js.map → chunk-H7PRHUBD.js.map} +0 -0
- /package/dist/{chunk-ETCVSZLG.js.map → chunk-HSBQJRV2.js.map} +0 -0
- /package/dist/{chunk-GZRDOVQN.js.map → chunk-HVKMJAEF.js.map} +0 -0
- /package/dist/{chunk-CSOYVTRX.js.map → chunk-IIPJKCZB.js.map} +0 -0
- /package/dist/{chunk-E57E5SCS.js.map → chunk-IRLH4NM2.js.map} +0 -0
- /package/dist/{chunk-4G45LJJP.js.map → chunk-IZRNVNPV.js.map} +0 -0
- /package/dist/{chunk-YSUSUZR4.js.map → chunk-JCJGYNIS.js.map} +0 -0
- /package/dist/{chunk-EU74U4GT.js.map → chunk-JDI7G6EA.js.map} +0 -0
- /package/dist/{chunk-QWPAQLYV.js.map → chunk-JFLKSD5V.js.map} +0 -0
- /package/dist/{chunk-KQS72GCR.js.map → chunk-LJOIZPJH.js.map} +0 -0
- /package/dist/{chunk-U27G4E5G.js.map → chunk-LLGDVG52.js.map} +0 -0
- /package/dist/{chunk-JGW2EUCQ.js.map → chunk-PMRUMGK6.js.map} +0 -0
- /package/dist/{chunk-3G6YU5YD.js.map → chunk-PSNN25DW.js.map} +0 -0
- /package/dist/{chunk-LRGSLV7M.js.map → chunk-PYHOAXTI.js.map} +0 -0
- /package/dist/{chunk-75U2FR7U.js.map → chunk-QCI73Z7C.js.map} +0 -0
- /package/dist/{chunk-EHMMRZOZ.js.map → chunk-QICOU4RY.js.map} +0 -0
- /package/dist/{chunk-K4WIUTNH.js.map → chunk-RFH7U5LT.js.map} +0 -0
- /package/dist/{chunk-4SGDYYWV.js.map → chunk-RPKJHYVE.js.map} +0 -0
- /package/dist/{chunk-DYDACAK2.js.map → chunk-TGSMU3F2.js.map} +0 -0
- /package/dist/{chunk-MJFDJTDC.js.map → chunk-TIRJV2LW.js.map} +0 -0
- /package/dist/{chunk-QRA3XVJX.js.map → chunk-UDTME32W.js.map} +0 -0
- /package/dist/{chunk-LAM6UDFV.js.map → chunk-WMOJIOIG.js.map} +0 -0
- /package/dist/{chunk-LLLY5IBK.js.map → chunk-WR2YKUIW.js.map} +0 -0
- /package/dist/{chunk-KYI3CM42.js.map → chunk-X6E7TT3A.js.map} +0 -0
- /package/dist/{chunk-QN7XQEIT.js.map → chunk-YIIC5IDU.js.map} +0 -0
- /package/dist/{chunk-JDJOAL4B.js.map → chunk-YSR3DXGC.js.map} +0 -0
- /package/dist/{chunk-LBJBNWS2.js.map → chunk-YTHQHH5U.js.map} +0 -0
- /package/dist/{chunk-JF6YSHJM.js.map → chunk-ZPGHA7EO.js.map} +0 -0
- /package/dist/{chunk-YG56A6XY.js.map → chunk-ZS4JADYY.js.map} +0 -0
- /package/dist/{forget-5TWK7CZT.js.map → forget-SZ2BXDGF.js.map} +0 -0
package/dist/causal-retrieval.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readChainIndex,
|
|
3
3
|
resolveChainsDir
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IRLH4NM2.js";
|
|
5
5
|
import "./chunk-B7RWBZXW.js";
|
|
6
6
|
import {
|
|
7
7
|
readCausalTrajectoryRecords,
|
|
8
8
|
searchCausalTrajectories
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-ALNZEWGN.js";
|
|
10
|
+
import "./chunk-DJ7HMNSL.js";
|
|
11
11
|
import "./chunk-A2IYSXDQ.js";
|
|
12
12
|
import "./chunk-P77QX3ID.js";
|
|
13
13
|
import {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as GraphEdge } from './graph-444E-DrF.js';
|
|
2
2
|
import { CausalTrajectoryRecord } from './causal-trajectory.js';
|
|
3
3
|
import './capabilities.js';
|
|
4
|
-
import './types-
|
|
4
|
+
import './types-DWHOxlZP.js';
|
|
5
5
|
import './message-parts/index.js';
|
|
6
6
|
import './bounded-jsonl-state.js';
|
|
7
7
|
import './operator-doctor-types.js';
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
resolveCausalTrajectoryStoreDir,
|
|
10
10
|
searchCausalTrajectories,
|
|
11
11
|
validateCausalTrajectoryRecord
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-ALNZEWGN.js";
|
|
13
|
+
import "./chunk-DJ7HMNSL.js";
|
|
14
14
|
import "./chunk-A2IYSXDQ.js";
|
|
15
15
|
import "./chunk-P77QX3ID.js";
|
|
16
16
|
import "./chunk-PZ5AY32C.js";
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
LcmDag
|
|
3
|
-
} from "./chunk-7N4KAIGN.js";
|
|
4
|
-
import {
|
|
5
|
-
LcmWorkQueue
|
|
6
|
-
} from "./chunk-TPDBFYEG.js";
|
|
7
|
-
import {
|
|
8
|
-
assembleCompressedHistoryWithTrace
|
|
9
|
-
} from "./chunk-UXPUUL3G.js";
|
|
10
1
|
import {
|
|
11
2
|
ensureLcmStateDir,
|
|
12
3
|
openLcmDatabase
|
|
@@ -17,6 +8,15 @@ import {
|
|
|
17
8
|
import {
|
|
18
9
|
LcmArchive
|
|
19
10
|
} from "./chunk-WVP2I6C5.js";
|
|
11
|
+
import {
|
|
12
|
+
LcmDag
|
|
13
|
+
} from "./chunk-7N4KAIGN.js";
|
|
14
|
+
import {
|
|
15
|
+
LcmWorkQueue
|
|
16
|
+
} from "./chunk-TPDBFYEG.js";
|
|
17
|
+
import {
|
|
18
|
+
assembleCompressedHistoryWithTrace
|
|
19
|
+
} from "./chunk-UXPUUL3G.js";
|
|
20
20
|
import {
|
|
21
21
|
estimateTokenCount
|
|
22
22
|
} from "./chunk-TOTT6S2V.js";
|
|
@@ -404,6 +404,18 @@ ${preview}`,
|
|
|
404
404
|
depth: best.depth
|
|
405
405
|
};
|
|
406
406
|
}
|
|
407
|
+
/**
|
|
408
|
+
* Retrieve raw archived messages for a turn range (inclusive bounds),
|
|
409
|
+
* read-only and unshaped — no token-budget trimming (issue #2331
|
|
410
|
+
* episodic-context). Callers own truncation and cleaning.
|
|
411
|
+
*/
|
|
412
|
+
async getTurnRange(sessionId, fromTurn, toTurn) {
|
|
413
|
+
if (!this.config.enabled) return [];
|
|
414
|
+
const normalizedSessionId = normalizeLcmSessionId(sessionId);
|
|
415
|
+
if (!normalizedSessionId) return [];
|
|
416
|
+
await this.ensureInitialized();
|
|
417
|
+
return this.archive.getMessages(normalizedSessionId, fromTurn, toTurn);
|
|
418
|
+
}
|
|
407
419
|
/** Retrieve raw messages for a turn range (lossless expansion). */
|
|
408
420
|
async expandContext(sessionId, fromTurn, toTurn, maxTokens) {
|
|
409
421
|
if (!this.config.enabled) return [];
|
|
@@ -556,4 +568,4 @@ export {
|
|
|
556
568
|
extractLcmConfig,
|
|
557
569
|
LcmEngine
|
|
558
570
|
};
|
|
559
|
-
//# sourceMappingURL=chunk-
|
|
571
|
+
//# sourceMappingURL=chunk-256FBCVX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lcm/engine.ts"],"sourcesContent":["import type Database from \"better-sqlite3\";\nimport { openLcmDatabase, ensureLcmStateDir } from \"./schema.js\";\nimport { LcmArchive, type LcmMessage, type LcmStructuredRecallMatch } from \"./archive.js\";\nimport { LcmDag } from \"./dag.js\";\nimport { LcmSummarizer, type SummarizeFn } from \"./summarizer.js\";\nimport {\n assembleCompressedHistoryWithTrace,\n type LcmRecallConfig,\n type LcmRecallWithTraceResult,\n} from \"./recall.js\";\nimport { LcmWorkQueue, type LcmObserveMessage } from \"./queue.js\";\nimport type { PluginConfig } from \"../types.js\";\nimport { estimateTokenCount } from \"../token-estimate.js\";\nimport { log } from \"../logger.js\";\nexport interface LcmEngineConfig {\n enabled: boolean;\n leafBatchSize: number;\n rollupFanIn: number;\n freshTailTurns: number;\n maxDepth: number;\n deterministicMaxTokens: number;\n archiveRetentionDays: number;\n recallBudgetShare: number;\n observeConcurrency: number;\n telemetryPrefilterEnabled: boolean;\n messagePartsEnabled: boolean;\n messagePartsRecallMaxResults: number;\n}\n\n/** An expanded archive row with stable lineage identity; content may be budget-truncated. */\nexport interface LcmExpandedMessage {\n id: number;\n session_id: string;\n turn_index: number;\n role: string;\n content: string;\n}\n\nfunction positiveInteger(value: unknown, fallback: number, min = 1): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n return Math.max(min, Math.floor(value));\n}\n\nexport function extractLcmConfig(cfg: PluginConfig): LcmEngineConfig {\n return {\n enabled: (cfg as any).lcmEnabled === true,\n leafBatchSize: positiveInteger((cfg as any).lcmLeafBatchSize, 8),\n rollupFanIn: positiveInteger((cfg as any).lcmRollupFanIn, 4, 2),\n freshTailTurns: positiveInteger((cfg as any).lcmFreshTailTurns, 16),\n maxDepth: positiveInteger((cfg as any).lcmMaxDepth, 5),\n deterministicMaxTokens: positiveInteger((cfg as any).lcmDeterministicMaxTokens, 512),\n archiveRetentionDays: positiveInteger((cfg as any).lcmArchiveRetentionDays, 90, 0),\n recallBudgetShare: (cfg as any).lcmRecallBudgetShare ?? 0.15,\n observeConcurrency:\n typeof (cfg as any).lcmObserveConcurrency === \"number\" &&\n Number.isFinite((cfg as any).lcmObserveConcurrency)\n ? Math.max(1, Math.floor((cfg as any).lcmObserveConcurrency))\n : 1,\n telemetryPrefilterEnabled: (cfg as any).lcmTelemetryPrefilterEnabled !== false,\n messagePartsEnabled: (cfg as any).messagePartsEnabled === true,\n messagePartsRecallMaxResults:\n typeof (cfg as any).messagePartsRecallMaxResults === \"number\"\n ? Math.max(0, Math.floor((cfg as any).messagePartsRecallMaxResults))\n : 6,\n };\n}\n\nfunction normalizeLcmSessionId(sessionId: string): string {\n return sessionId.trim();\n}\n\nfunction normalizeOptionalLcmSessionId(sessionId?: string): string | undefined {\n if (sessionId === undefined) {\n return undefined;\n }\n const normalized = normalizeLcmSessionId(sessionId);\n return normalized.length > 0 ? normalized : undefined;\n}\n\nconst EMPTY_LCM_STATS = {\n totalMessages: 0,\n totalSummaryNodes: 0,\n maxDepth: -1,\n} as const;\n\nexport class LcmEngine {\n private db: Database.Database | null = null;\n private archive: LcmArchive | null = null;\n private dag: LcmDag | null = null;\n private summarizer: LcmSummarizer | null = null;\n private observeQueue: LcmWorkQueue | null = null;\n private closed = false;\n private readonly config: LcmEngineConfig;\n private readonly memoryDir: string;\n private initPromise: Promise<void> | null = null;\n private readonly pendingObserveInitCounts = new Map<string, number>();\n private readonly pendingObserveInitWaiters = new Map<string, Array<() => void>>();\n private readonly pendingObserveInitIdleWaiters: Array<() => void> = [];\n\n constructor(\n pluginConfig: PluginConfig,\n private readonly summarizeFn: SummarizeFn,\n ) {\n this.config = extractLcmConfig(pluginConfig);\n this.memoryDir = pluginConfig.memoryDir;\n }\n\n get enabled(): boolean {\n return this.config.enabled;\n }\n\n /** Lazy init — open database on first use. */\n async ensureInitialized(): Promise<void> {\n if (this.closed) return;\n if (this.db) return;\n if (this.initPromise) {\n await this.initPromise;\n return;\n }\n this.initPromise = this.doInit().catch((err) => {\n // Reset so next call retries instead of caching the failure\n this.initPromise = null;\n throw err;\n });\n await this.initPromise;\n }\n\n private async doInit(): Promise<void> {\n await ensureLcmStateDir(this.memoryDir);\n const db = openLcmDatabase(this.memoryDir);\n const archive = new LcmArchive(db);\n const dag = new LcmDag(db);\n const { telemetryPrefilterEnabled } = this.config;\n const summarizer = new LcmSummarizer(\n archive,\n dag,\n this.summarizeFn,\n {\n leafBatchSize: this.config.leafBatchSize,\n rollupFanIn: this.config.rollupFanIn,\n maxDepth: this.config.maxDepth,\n deterministicMaxTokens: this.config.deterministicMaxTokens,\n telemetryPrefilterEnabled,\n },\n );\n const observeQueue = new LcmWorkQueue({\n concurrency: this.config.observeConcurrency,\n worker: async (sessionId, messages) => {\n await this.processObserveMessages(sessionId, messages);\n },\n hooks: {\n onJobStart: ({ sessionId, depth, inFlight, waitMs }) => {\n log.debug(\n `LCM observe queue start: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms`,\n );\n },\n onJobFinish: ({\n sessionId,\n depth,\n inFlight,\n waitMs,\n runMs,\n totalMs,\n error,\n }) => {\n if (error) {\n log.error(\n `LCM observe queue failure: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms, run=${runMs}ms, total=${totalMs}ms, error=${error}`,\n );\n return;\n }\n\n log.debug(\n `LCM observe queue finish: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms, run=${runMs}ms, total=${totalMs}ms`,\n );\n },\n },\n });\n\n if (this.closed) {\n db.close();\n return;\n }\n\n this.db = db;\n this.archive = archive;\n this.dag = dag;\n this.summarizer = summarizer;\n this.observeQueue = observeQueue;\n log.info(\"LCM engine initialized\");\n }\n\n /**\n * Enqueue messages from agent_end hook.\n * The queue worker performs the archive append and incremental summarization.\n */\n async observeMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): Promise<void> {\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n this.enqueueObserveMessages(normalizedSessionId, messages);\n }\n\n /** Enqueue an observe job without waiting for worker completion. */\n enqueueObserveMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): void {\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n if (messages.length === 0) return;\n\n this.reservePendingObserveInit(normalizedSessionId);\n\n void this.ensureInitialized()\n .then(() => {\n if (this.closed || !this.observeQueue) return;\n this.observeQueue.enqueue(normalizedSessionId, messages);\n log.debug(\n `LCM observe enqueued: session=${normalizedSessionId}, depth=${this.observeQueue.depth}, inFlight=${this.observeQueue.inFlightCount}`,\n );\n })\n .catch((err) => {\n if (this.closed) return;\n log.error(`LCM observe enqueue initialization error: ${err}`);\n })\n .finally(() => {\n this.releasePendingObserveInit(normalizedSessionId);\n });\n }\n\n private async processObserveMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): Promise<void> {\n if (this.closed) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.summarizer) return;\n\n if (messages.length === 0) return;\n\n const currentMax = this.archive.getMaxTurnIndex(sessionId);\n const { messagePartsEnabled } = this.config;\n const newMessages = messages.map((m, i) => ({\n turnIndex: currentMax + 1 + i,\n role: m.role,\n content: m.content,\n parts: messagePartsEnabled ? m.parts : undefined,\n rawContent: messagePartsEnabled ? m.rawContent : undefined,\n sourceFormat: messagePartsEnabled ? m.sourceFormat : undefined,\n }));\n\n this.archive.appendMessages(sessionId, newMessages, {\n messagePartsEnabled,\n });\n\n // Trigger incremental summarization inside the worker, after append.\n try {\n await this.summarizer.summarizeIncremental(sessionId);\n } catch (err) {\n log.debug(`LCM incremental summarization error: ${err}`);\n }\n }\n\n get observeQueueDepth(): number {\n return this.observeQueue?.depth ?? 0;\n }\n\n get observeQueueInFlightCount(): number {\n return this.observeQueue?.inFlightCount ?? 0;\n }\n\n async waitForObserveQueueIdle(): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n await this.ensureInitialized();\n if (this.closed) return;\n await this.waitForPendingObserveInitIdle();\n await this.observeQueue?.whenIdle();\n }\n\n async waitForSessionObserveIdle(sessionId: string): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n if (this.closed) return;\n await this.waitForPendingObserveInitIdle(normalizedSessionId);\n await this.observeQueue?.whenSessionIdle(normalizedSessionId);\n }\n\n private reservePendingObserveInit(sessionId: string): void {\n const count = this.pendingObserveInitCounts.get(sessionId) ?? 0;\n this.pendingObserveInitCounts.set(sessionId, count + 1);\n }\n\n private releasePendingObserveInit(sessionId: string): void {\n const count = this.pendingObserveInitCounts.get(sessionId);\n if (!count) return;\n\n if (count === 1) {\n this.pendingObserveInitCounts.delete(sessionId);\n const waiters = this.pendingObserveInitWaiters.get(sessionId) ?? [];\n this.pendingObserveInitWaiters.delete(sessionId);\n for (const resolve of waiters) resolve();\n if (this.pendingObserveInitCounts.size === 0) {\n const idleWaiters = this.pendingObserveInitIdleWaiters.splice(\n 0,\n this.pendingObserveInitIdleWaiters.length,\n );\n for (const resolve of idleWaiters) resolve();\n }\n return;\n }\n\n this.pendingObserveInitCounts.set(sessionId, count - 1);\n }\n\n private async waitForPendingObserveInitIdle(sessionId?: string): Promise<void> {\n if (sessionId) {\n if (!this.pendingObserveInitCounts.has(sessionId)) return;\n await new Promise<void>((resolve) => {\n const waiters = this.pendingObserveInitWaiters.get(sessionId) ?? [];\n waiters.push(resolve);\n this.pendingObserveInitWaiters.set(sessionId, waiters);\n });\n return;\n }\n\n if (this.pendingObserveInitCounts.size === 0) return;\n await new Promise<void>((resolve) => {\n this.pendingObserveInitIdleWaiters.push(resolve);\n });\n }\n\n /** Build the compressed history recall section for a session. */\n async assembleRecall(\n sessionId: string,\n budgetChars: number,\n ): Promise<string> {\n return (await this.assembleRecallWithTrace(sessionId, budgetChars)).text;\n }\n\n /** Build compressed recall plus content-free selected-summary receipts. */\n async assembleRecallWithTrace(\n sessionId: string,\n budgetChars: number,\n ): Promise<LcmRecallWithTraceResult> {\n if (!this.config.enabled) return { text: \"\", selectedSummaries: [] };\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return { text: \"\", selectedSummaries: [] };\n await this.ensureInitialized();\n\n const effectiveBudget = Math.ceil(\n budgetChars * this.config.recallBudgetShare,\n );\n if (effectiveBudget <= 0) return { text: \"\", selectedSummaries: [] };\n\n return assembleCompressedHistoryWithTrace(this.dag!, this.archive!, normalizedSessionId, {\n freshTailTurns: this.config.freshTailTurns,\n budgetChars: effectiveBudget,\n });\n }\n\n async searchStructuredParts(\n sessionId: string,\n query: string,\n limit = this.config.messagePartsRecallMaxResults,\n ): Promise<LcmStructuredRecallMatch[]> {\n const { messagePartsEnabled } = this.config;\n if (!this.config.enabled || !messagePartsEnabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n if (!this.archive) return [];\n return this.archive.searchStructuredParts(query, limit, normalizedSessionId);\n }\n\n formatStructuredRecall(\n matches: LcmStructuredRecallMatch[],\n budgetChars: number,\n ): string {\n if (matches.length === 0 || budgetChars <= 0) return \"\";\n const lines: string[] = [];\n let used = \"## Structured Session Matches\\n\\n\".length;\n for (const match of matches) {\n const label = match.file_path\n ? `${match.kind} ${match.file_path}`\n : match.tool_name\n ? `${match.kind} ${match.tool_name}`\n : match.kind;\n const excerpt = match.content.replace(/\\s+/g, \" \").slice(0, 220);\n const line = `- turn ${match.turn_index} (${match.role}): ${label} — ${excerpt}`;\n if (used + line.length + 1 > budgetChars) break;\n lines.push(line);\n used += line.length + 1;\n }\n return lines.length > 0 ? `## Structured Session Matches\\n\\n${lines.join(\"\\n\")}` : \"\";\n }\n\n /** Flush pending summaries before compaction (called from before_compaction hook). */\n async preCompactionFlush(sessionId: string): Promise<void> {\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n await this.waitForSessionObserveIdle(normalizedSessionId);\n\n try {\n await this.summarizer!.summarizeIncremental(normalizedSessionId);\n } catch (err) {\n log.debug(`LCM pre-compaction flush error: ${err}`);\n }\n }\n\n /** Record a compaction event with real token counts (called from after_compaction hook). */\n async recordCompaction(\n sessionId: string,\n tokensBefore: number,\n tokensAfter: number,\n ): Promise<void> {\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n await this.waitForSessionObserveIdle(normalizedSessionId);\n\n const maxTurn = this.archive!.getMaxTurnIndex(normalizedSessionId);\n\n this.dag!.recordCompaction(normalizedSessionId, maxTurn, tokensBefore, tokensAfter);\n log.info(\n `LCM compaction recorded: session=${normalizedSessionId}, turn=${maxTurn}, tokens ${tokensBefore}→${tokensAfter}`,\n );\n }\n\n /** Verify archive coverage after compaction. */\n async verifyPostCompaction(sessionId: string): Promise<void> {\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n\n const msgCount = this.archive!.getMessageCount(normalizedSessionId);\n const nodeCount = this.dag!.getNodeCount(normalizedSessionId);\n log.debug(\n `LCM post-compaction verify: session=${normalizedSessionId}, messages=${msgCount}, summaryNodes=${nodeCount}`,\n );\n }\n\n // ── MCP Tool implementations ──\n\n /** Search across all conversation history via FTS (snippet mode). */\n async searchContext(\n query: string,\n limit: number,\n sessionId?: string,\n sessionPrefix?: string,\n ): Promise<\n Array<{\n turn_index: number;\n role: string;\n snippet: string;\n session_id: string;\n }>\n > {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) return [];\n const normalizedSessionPrefix = normalizeOptionalLcmSessionId(sessionPrefix);\n if (sessionPrefix !== undefined && !normalizedSessionPrefix) return [];\n await this.ensureInitialized();\n return this.archive!.search(query, limit, normalizedSessionId, normalizedSessionPrefix);\n }\n\n /** Search via FTS returning full message content (not snippets). */\n async searchContextFull(\n query: string,\n limit: number,\n sessionId?: string,\n sessionPrefix?: string,\n ): Promise<\n Array<{\n id: number;\n turn_index: number;\n role: string;\n content: string;\n session_id: string;\n score: number;\n }>\n > {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) return [];\n const normalizedSessionPrefix = normalizeOptionalLcmSessionId(sessionPrefix);\n if (sessionPrefix !== undefined && !normalizedSessionPrefix) return [];\n await this.ensureInitialized();\n return this.archive!.searchWithContent(\n query,\n limit,\n normalizedSessionId,\n 1000,\n normalizedSessionPrefix,\n );\n }\n\n /** Get a compressed summary of a turn range. */\n async describeContext(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n ): Promise<{ summary: string; turn_count: number; depth: number } | null> {\n if (!this.config.enabled) return null;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return null;\n await this.ensureInitialized();\n\n const nodes = this.dag!.getCoveringNodes(normalizedSessionId, fromTurn, toTurn);\n if (nodes.length === 0) {\n // No summary exists — build a description from raw messages\n const messages = this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n if (messages.length === 0) return null;\n const preview = messages\n .slice(0, 5)\n .map((m) => `[${m.role}] ${m.content.slice(0, 100)}`)\n .join(\"\\n\");\n return {\n summary: `No summary available for this range. Preview of ${messages.length} messages:\\n${preview}`,\n turn_count: messages.length,\n depth: -1,\n };\n }\n\n // Use the deepest covering node\n const best = nodes[0]; // Already sorted by depth DESC\n return {\n summary: best.summary_text,\n turn_count: best.msg_end - best.msg_start + 1,\n depth: best.depth,\n };\n }\n\n /**\n * Retrieve raw archived messages for a turn range (inclusive bounds),\n * read-only and unshaped — no token-budget trimming (issue #2331\n * episodic-context). Callers own truncation and cleaning.\n */\n async getTurnRange(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n ): Promise<LcmMessage[]> {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n return this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n }\n\n /** Retrieve raw messages for a turn range (lossless expansion). */\n async expandContext(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n maxTokens: number,\n ): Promise<LcmExpandedMessage[]> {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n\n const messages = this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n if (messages.length === 0) return [];\n\n // Enforce the token budget while keeping the existing first/last shape.\n const tokenBudget = Math.max(0, Math.floor(maxTokens));\n if (tokenBudget === 0) return [];\n const totalTokens = messages.reduce(\n (sum, message) => sum + estimateTokenCount(message.content),\n 0,\n );\n if (totalTokens <= tokenBudget) {\n return messages.map((m) => ({\n id: m.id,\n session_id: m.session_id,\n turn_index: m.turn_index,\n role: m.role,\n content: m.content,\n }));\n }\n\n const result: LcmExpandedMessage[] = [];\n const lastMsg = messages[messages.length - 1];\n const reservedLastTokens = Math.min(\n estimateTokenCount(lastMsg.content),\n Math.max(1, Math.floor(tokenBudget * 0.3)),\n );\n let remainingTokens = tokenBudget - reservedLastTokens;\n\n for (let i = 0; i < messages.length - 1; i++) {\n if (remainingTokens <= 0) break;\n const content = truncateToTokenBudget(\n messages[i].content,\n remainingTokens,\n );\n if (!content) continue;\n result.push({\n id: messages[i].id,\n session_id: messages[i].session_id,\n turn_index: messages[i].turn_index,\n role: messages[i].role,\n content,\n });\n remainingTokens -= estimateTokenCount(content);\n }\n\n const lastContent = truncateToTokenBudget(\n lastMsg.content,\n reservedLastTokens + remainingTokens,\n );\n if (lastContent) {\n result.push({\n id: lastMsg.id,\n session_id: lastMsg.session_id,\n turn_index: lastMsg.turn_index,\n role: lastMsg.role,\n content: lastContent,\n });\n }\n return result;\n }\n\n\n /** Get statistics about the LCM archive. */\n async getStats(sessionId?: string): Promise<{\n totalMessages: number;\n totalSummaryNodes: number;\n maxDepth: number;\n maxTurnIndex?: number;\n }> {\n if (!this.config.enabled)\n return { totalMessages: 0, totalSummaryNodes: 0, maxDepth: -1 };\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) {\n return { ...EMPTY_LCM_STATS };\n }\n await this.ensureInitialized();\n\n if (normalizedSessionId) {\n return {\n totalMessages: this.archive!.getMessageCount(normalizedSessionId),\n totalSummaryNodes: this.dag!.getNodeCount(normalizedSessionId),\n maxDepth: this.dag!.getMaxDepth(normalizedSessionId),\n maxTurnIndex: this.archive!.getMaxTurnIndex(normalizedSessionId),\n };\n }\n\n return {\n totalMessages: this.archive!.getTotalMessageCount(),\n totalSummaryNodes: 0, // Would need a global count query\n maxDepth: -1,\n };\n }\n\n /** Clear all LCM archive and summary state for one session. */\n async clearSession(sessionId: string): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.dag) return;\n await this.waitForSessionObserveIdle(normalizedSessionId);\n this.dag.deleteSession(normalizedSessionId);\n this.archive.deleteSession(normalizedSessionId);\n }\n\n /** Clear all LCM archive and summary state without closing the engine. */\n async clearAll(): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.dag) return;\n await this.waitForObserveQueueIdle();\n this.dag.deleteAll();\n this.archive.deleteAll();\n }\n\n /** Prune old data beyond retention period. */\n async prune(): Promise<{ messagesPruned: number; nodesPruned: number }> {\n if (!this.config.enabled) return { messagesPruned: 0, nodesPruned: 0 };\n await this.ensureInitialized();\n\n const messagesPruned = this.archive!.pruneOldMessages(\n this.config.archiveRetentionDays,\n );\n const nodesPruned = this.dag!.pruneOldNodes(\n this.config.archiveRetentionDays,\n );\n return { messagesPruned, nodesPruned };\n }\n\n /** Close the database connection. */\n close(): void {\n this.closed = true;\n if (this.db) {\n this.db.close();\n }\n this.db = null;\n this.archive = null;\n this.dag = null;\n this.summarizer = null;\n this.observeQueue = null;\n this.initPromise = null;\n }\n}\nfunction truncateToTokenBudget(text: string, maxTokens: number): string {\n if (maxTokens <= 0) return \"\";\n if (estimateTokenCount(text) <= maxTokens) return text;\n const codePoints = [...text];\n let low = 0;\n let high = codePoints.length;\n while (low < high) {\n const mid = Math.ceil((low + high) / 2);\n if (estimateTokenCount(codePoints.slice(0, mid).join(\"\")) <= maxTokens) {\n low = mid;\n } else {\n high = mid - 1;\n }\n }\n return codePoints.slice(0, low).join(\"\");\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-R7TZ2HCS.js";
|
|
4
4
|
import {
|
|
5
5
|
normalizeRecallTokens
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DJ7HMNSL.js";
|
|
7
7
|
import {
|
|
8
8
|
sanitizeMemoryContent
|
|
9
9
|
} from "./chunk-5GKPFL3S.js";
|
|
@@ -69,4 +69,4 @@ export {
|
|
|
69
69
|
extractionAttributes,
|
|
70
70
|
extractionCueAnchors
|
|
71
71
|
};
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
72
|
+
//# sourceMappingURL=chunk-2TYIAKU5.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
rebuildMemoryProjection
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4IZ2IT7D.js";
|
|
4
4
|
|
|
5
5
|
// src/convergence-refresh.ts
|
|
6
6
|
async function refreshConvergedNamespaces(namespaces, namespaceSearchRouter, getStorage, searchEnabled) {
|
|
@@ -32,4 +32,4 @@ async function refreshConvergedNamespaces(namespaces, namespaceSearchRouter, get
|
|
|
32
32
|
export {
|
|
33
33
|
refreshConvergedNamespaces
|
|
34
34
|
};
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
35
|
+
//# sourceMappingURL=chunk-347ZR6D4.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-SOBJ6NEY.js";
|
|
4
4
|
import {
|
|
5
5
|
summarizeDisclosureTokens
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QICOU4RY.js";
|
|
7
7
|
import {
|
|
8
8
|
summarizeRetrievedMemoryProvenance
|
|
9
9
|
} from "./chunk-I4WBNM3M.js";
|
|
@@ -606,4 +606,4 @@ export {
|
|
|
606
606
|
renderRecallExplain,
|
|
607
607
|
parseRecallExplainFormat
|
|
608
608
|
};
|
|
609
|
-
//# sourceMappingURL=chunk-
|
|
609
|
+
//# sourceMappingURL=chunk-3F3CVVDS.js.map
|
|
@@ -9,14 +9,14 @@ import {
|
|
|
9
9
|
} from "./chunk-666A3MOW.js";
|
|
10
10
|
import {
|
|
11
11
|
rebuildMemoryLifecycleLedger
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-TIRJV2LW.js";
|
|
13
13
|
import {
|
|
14
14
|
planNamespaceMaintenance,
|
|
15
15
|
runNamespaceMaintenanceBatchPlan
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-4HO3542O.js";
|
|
17
17
|
import {
|
|
18
18
|
rebuildMemoryProjection
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-4IZ2IT7D.js";
|
|
20
20
|
import {
|
|
21
21
|
activityDayWindow,
|
|
22
22
|
activityDigestPath,
|
|
@@ -1719,4 +1719,4 @@ export {
|
|
|
1719
1719
|
ActivitySyncScheduler,
|
|
1720
1720
|
MaintenanceScheduler
|
|
1721
1721
|
};
|
|
1722
|
-
//# sourceMappingURL=chunk-
|
|
1722
|
+
//# sourceMappingURL=chunk-3MA7JVXN.js.map
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
computeLegacyContentHash
|
|
2
|
+
computeLegacyContentHash,
|
|
3
|
+
isUnambiguousLegacyContentHash,
|
|
4
|
+
normalizeLegacyContent
|
|
3
5
|
} from "./chunk-5FVVY2EB.js";
|
|
4
6
|
import {
|
|
5
7
|
serializeMutations,
|
|
@@ -553,7 +555,9 @@ var TombstoneStore = class {
|
|
|
553
555
|
const currentHash = this.options.hashContent(m.rawContent);
|
|
554
556
|
const currentNormalizedText = this.options.normalizeText(m.rawContent);
|
|
555
557
|
const persistedHash = m.contentHash;
|
|
556
|
-
const
|
|
558
|
+
const legacyBodyHash = computeLegacyContentHash(m.rawContent);
|
|
559
|
+
const repairEmptySkeleton = normalizeLegacyContent(m.rawContent).length === 0 && persistedHash === legacyBodyHash;
|
|
560
|
+
const preserveOverride = persistedHash !== void 0 && persistedHash !== currentHash && !repairEmptySkeleton && !isUnambiguousLegacyContentHash(m.rawContent, persistedHash, currentNormalizedText);
|
|
557
561
|
return {
|
|
558
562
|
id: existingBySource.get(`${m.memoryId}\0${m.supersessionKey ?? ""}`) ?? newTombstoneId(),
|
|
559
563
|
...preserveOverride ? { currentContentHashAlias: currentHash } : {},
|
|
@@ -659,4 +663,4 @@ export {
|
|
|
659
663
|
applyTombstoneResurrectionGate,
|
|
660
664
|
buildRetiredFactTombstoneInputs
|
|
661
665
|
};
|
|
662
|
-
//# sourceMappingURL=chunk-
|
|
666
|
+
//# sourceMappingURL=chunk-46WM6JX2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lifecycle/tombstones.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// lifecycle/tombstones.ts — Tombstone store + non-resurrection invariant\n// (issue #1579)\n//\n// A \"tombstone\" records that a fact has been retired (corrected, superseded,\n// or retracted) so that the SAME fact cannot silently come back to life through\n// any of the five resurrection paths:\n//\n// 1. Re-extraction (session replay, re-observation)\n// 2. Importers (capsule / import-* payloads)\n// 3. Consolidation merges\n// 4. Dreams (REM re-derivation)\n// 5. Pattern reinforcement (duplicate promotion)\n//\n// The invariant is enforced at the SINGLE storage persist path\n// (`StorageManager.writeMemory` — the same chokepoint that records catalog\n// writes, issue #1522). Every write path funnels through it, so paths (a)–(e)\n// are blocked WITHOUT per-path code.\n//\n// File-first / rebuildable (the repo's storage philosophy): the JSONL at\n// `<stateDir>/tombstones.jsonl` is a cache of truth. The authoritative sources\n// are the memory files themselves (status: superseded/retracted) and the\n// `corrections/` records. `rebuildTombstonesFromStorage` reconstructs the\n// JSONL from those sources.\n//\n// Design rules honored (issue #1579 design section):\n// - Hash `rawContent` exactly as the dedup index does — one helper\n// (`ContentHashIndex.computeHash` / `normalizeContent`), never a second\n// (checklist §13; rule 23).\n// - Append-only log — never rewrite history; a later `kind: \"revocation\"`\n// entry re-allows (rule 25).\n// - Instance-scoped, never module-level (rule 11).\n// - Namespace-scoped — a tombstone in namespace A never blocks namespace B\n// (rule 42).\n// - Serialized appends with rejection recovery (rule 40).\n// - Never silent drop — a blocked write lands as pending_review + blockedBy\n// (rule 34).\n// - Do NOT register a blocked fact as an active dedup/index entry (rule 44).\n// - Off = pre-feature behavior for rollback safety (rule 30).\n// - Semantic tier (4) ships dark, off by default (rule 48).\n// ---------------------------------------------------------------------------\n\nimport { serializeMutations, withHeldFileLock } from \"../utils/serialize-mutations.js\";\nimport {\n computeLegacyContentHash,\n isUnambiguousLegacyContentHash,\n normalizeLegacyContent,\n} from \"../content-hash.js\";\n\n/** Why a tombstone was emitted. */\nexport type TombstoneReason =\n | \"correction\"\n | \"supersession\"\n | \"retraction\"\n | \"contradiction_resolution\";\n\n/** Who emitted the tombstone. */\nexport type TombstoneCreatedBy =\n | \"user_correction\"\n | \"contradiction_resolution\"\n | \"supersession\"\n | \"chat\";\n\n/** Tier that matched on lookup. */\nexport type TombstoneMatchTier = \"exact\" | \"normalized\" | \"keyed\" | \"semantic\";\n\n/**\n * A single append-only tombstone log entry.\n *\n * `kind: \"tombstone\"` blocks; `kind: \"revocation\"` re-allows. The log is\n * never rewritten — the NEWEST matching entry wins at lookup (rule 25).\n */\nexport interface TombstoneEntry {\n /** Stable tombstone id (`tomb-<ts>-<rand>`). */\n id: string;\n kind: \"tombstone\" | \"revocation\";\n reason: TombstoneReason;\n /** The memory that was retired. */\n sourceMemoryId: string;\n /** sha256 of the retired identity; explicit contentHashSource may define it. */\n contentHash: string;\n /** Current body hash retained alongside an ambiguous or explicit primary hash. */\n currentContentHashAlias?: string;\n /** Current normalized body used by the normalized lookup tier. */\n normalizedText: string;\n /** Version of the current body identity fields. */\n normalizerVersion?: number;\n entityRef?: string;\n /** Structured-attribute supersession key when one existed. */\n supersessionKey?: string;\n /** Stable operation identity for crash-recovery replay. */\n operationKey?: string;\n /** Namespace scope (rule 42). */\n namespace: string;\n createdAt: string;\n createdBy: TombstoneCreatedBy;\n /** For `kind: \"revocation\"`: the tombstone id being revoked. */\n revokes?: string;\n}\n\n/** A positive block decision returned by `TombstoneStore.lookup`. */\nexport interface TombstoneMatch {\n tombstoneId: string;\n matchedTier: TombstoneMatchTier;\n reason: TombstoneReason;\n}\n\n/** Inputs to a lookup. At least one discriminator must be present.\n *\n * Issue #1579 thread Ociag/Oci-W: `supersessionKeys` (plural) lets the write\n * chokepoint check EVERY derived key, not just the first. Emitters register\n * one tombstone per matched key (temporal-supersession, rebuild), so a block\n * can live on any later key; querying only `supersessionKeys[0]` missed it\n * and the retired fact resurrected as active. `supersessionKey` (singular)\n * remains for direct/unit callers; `lookup` checks the union of both. */\nexport interface TombstoneLookupQuery {\n contentHash?: string;\n normalizedText?: string;\n entityRef?: string;\n /** Single supersession key (direct/unit callers). */\n supersessionKey?: string;\n /** All derived supersession keys (write chokepoint). The keyed tier is\n * checked for each; the first active match wins. */\n supersessionKeys?: string[];\n namespace: string;\n}\n\n/** Configuration for a tombstone store instance. */\nexport interface TombstoneStoreOptions {\n enabled: boolean;\n semanticMatch: boolean;\n semanticThreshold: number;\n /** sha256 of raw content — wired to `ContentHashIndex.computeHash`. */\n hashContent: (raw: string) => string;\n /** Normalize raw content — wired to `ContentHashIndex.normalizeContent`. */\n normalizeText: (raw: string) => string;\n /**\n * Optional cosine similarity in [0, 1] for the semantic tier. When\n * undefined or when `semanticMatch` is false, the semantic tier is\n * skipped entirely.\n */\n semanticSimilarity?: (a: string, b: string) => number;\n /**\n * Resolve source identity candidates for bounded legacy sourceMemoryIds.\n * StorageManager reads the corpus before the tombstone write lock.\n */\n readonly sourceContentsForMemoryIds?: (\n sourceMemoryIds: readonly string[],\n ) => Promise<ReadonlyMap<string, string | readonly string[]>>;\n /** Maximum number of legacy entries considered during one load. */\n readonly legacyMigrationLimit?: number;\n /**\n * Cross-process write-lock timings for the tombstone JSONL mutation lock\n * (issue #1639). The secure-store append is a read-merge-write (read\n * encrypted → decrypt → concat → re-encrypt → atomic rename), so two\n * Remnic processes appending concurrently can each read the same contents\n * and the last writer drops the other's entry — breaking the\n * non-resurrection invariant. The lock serializes the mutation across\n * processes. When omitted, defaults that fit the short tombstone critical\n * section (mirroring the summary-snapshot lock): staleMs 30s, maxWaitMs 5s,\n * heartbeatMs floor(staleMs/3).\n */\n readonly lockStaleMs?: number;\n readonly lockMaxWaitMs?: number;\n readonly lockHeartbeatMs?: number;\n}\n\n/** Injected file I/O — the StorageManager wires its secure-store-aware\n * implementations so tombstones are encrypted at rest alongside other state.\n * `stat` is optional; when provided the store tracks the file mtime itself and\n * runs a cross-process staleness probe on each access (#1579). */\nexport interface TombstoneFileIo {\n read: (filePath: string) => Promise<string>;\n append: (filePath: string, content: string) => Promise<void>;\n write: (filePath: string, content: string) => Promise<void>;\n stat?: (filePath: string) => { mtimeMs: number };\n}\n\n/** Aggregate stats for `remnic doctor`. */\nexport interface TombstoneStats {\n count: number;\n revoked: number;\n lastAppendAt: string | null;\n corruptedLines: number;\n /** Whether the in-memory index matches the on-disk file (rebuild check). */\n loaded: boolean;\n}\n\nconst TOMBSTONE_NORMALIZER_VERSION = 2;\nconst DEFAULT_LEGACY_MIGRATION_LIMIT = 10_000;\n\nconst TOMBSTONE_PREFIX = \"tomb\";\n\nfunction newTombstoneId(): string {\n return `${TOMBSTONE_PREFIX}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/** Deterministic key for the keyed tier (namespace + entityRef + supersessionKey).\n *\n * The namespace is part of the discriminator so two namespace-scoped stores\n * that share the same backing `tombstones.jsonl` (namespaces disabled, or the\n * same directory used with different namespace configs) cannot overwrite each\n * other's index entries — a later tombstone for namespace B with the same\n * entity/key no longer evicts namespace A's entry (issue #1579 thread Ocs-O). */\nfunction keyedTierKey(namespace: string, entityRef: string, supersessionKey: string): string {\n return `${namespace}\\0${entityRef}\\0${supersessionKey}`;\n}\n\n/**\n * Parse one JSONL line into a TombstoneEntry, validating the discriminated\n * union. Returns `null` for malformed lines (rule 34 — skip with a counter,\n * never crash).\n */\nexport function parseTombstoneLine(line: string): TombstoneEntry | null {\n const trimmed = line.trim();\n if (trimmed.length === 0) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== \"object\") return null;\n const e = parsed as Record<string, unknown>;\n if (typeof e.id !== \"string\" || e.id.length === 0) return null;\n if (e.kind !== \"tombstone\" && e.kind !== \"revocation\") return null;\n if (\n e.reason !== \"correction\" &&\n e.reason !== \"supersession\" &&\n e.reason !== \"retraction\" &&\n e.reason !== \"contradiction_resolution\"\n ) {\n return null;\n }\n if (typeof e.sourceMemoryId !== \"string\") return null;\n if (typeof e.contentHash !== \"string\") return null;\n if (typeof e.normalizedText !== \"string\") return null;\n if (typeof e.namespace !== \"string\") return null;\n if (typeof e.createdAt !== \"string\") return null;\n if (\n e.createdBy !== \"user_correction\" &&\n e.createdBy !== \"contradiction_resolution\" &&\n e.createdBy !== \"supersession\" &&\n e.createdBy !== \"chat\"\n ) {\n return null;\n }\n const out: TombstoneEntry = {\n id: e.id,\n kind: e.kind,\n reason: e.reason,\n sourceMemoryId: e.sourceMemoryId,\n contentHash: e.contentHash,\n normalizedText: e.normalizedText,\n namespace: e.namespace,\n createdAt: e.createdAt,\n createdBy: e.createdBy,\n };\n if (typeof e.currentContentHashAlias === \"string\") {\n out.currentContentHashAlias = e.currentContentHashAlias;\n }\n if (typeof e.normalizerVersion === \"number\" && Number.isInteger(e.normalizerVersion)) {\n out.normalizerVersion = e.normalizerVersion;\n }\n if (typeof e.operationKey === \"string\") out.operationKey = e.operationKey;\n if (typeof e.entityRef === \"string\") out.entityRef = e.entityRef;\n if (typeof e.supersessionKey === \"string\") out.supersessionKey = e.supersessionKey;\n if (typeof e.revokes === \"string\") out.revokes = e.revokes;\n return out;\n}\n\n/**\n * The instance-scoped tombstone store. One per StorageManager (rule 11),\n * namespace-scoped via `namespace` + the on-disk path (rule 42).\n *\n * The in-memory index is built lazily on first access and invalidated on\n * append + by the StorageManager's cache-invalidation chokepoint (rule 25).\n */\nexport class TombstoneStore {\n private entries: TombstoneEntry[] = [];\n /** contentHash → tombstone id (newest) — exact tier. */\n private readonly byHash = new Map<string, string>();\n /** normalizedText → tombstone id (newest) — normalized tier. */\n private readonly byNormalized = new Map<string, string>();\n /** entityRef\\0supersessionKey → tombstone id (newest) — keyed tier. */\n private readonly byKey = new Map<string, string>();\n /** Tombstone ids that have a later revocation entry. */\n private readonly revokedIds = new Set<string>();\n /** id → entry index (newest only, for revocation lookups). */\n private readonly byId = new Map<string, TombstoneEntry>();\n private loaded = false;\n private loadPromise: Promise<void> | null = null;\n private corruptedLines = 0;\n private lastAppendAt: string | null = null;\n /**\n * Last-seen mtime of the JSONL file (cross-process staleness probe, #1579).\n * Tracked inside the store so the StorageManager wiring stays thin. When the\n * file's mtime advances past this value between accesses, the in-memory index\n * is stale (a peer process appended) and is reloaded before the next lookup.\n */\n private fileMtimeMs = 0;\n\n constructor(\n private readonly filePath: string,\n private readonly namespace: string,\n private readonly options: TombstoneStoreOptions,\n private readonly io: TombstoneFileIo,\n ) {\n const limit = this.options.legacyMigrationLimit;\n if (limit !== undefined && (!Number.isFinite(limit) || !Number.isInteger(limit) || limit < 0)) {\n throw new Error(\"legacyMigrationLimit must be a finite non-negative integer\");\n }\n this.lockStaleMs = this.options.lockStaleMs ?? 30_000;\n this.lockMaxWaitMs = this.options.lockMaxWaitMs ?? 5_000;\n this.lockHeartbeatMs =\n this.options.lockHeartbeatMs ?? Math.max(100, Math.floor(this.lockStaleMs / 3));\n }\n\n /**\n * Resolved cross-process write-lock timings (issue #1639). Defaults mirror\n * the summary-snapshot lock: a tombstone append critical section is\n * sub-second, so a stale lock older than 30s is a crashed holder; bounded\n * acquisition gives up after 5s and strict-fails rather than clobbering a\n * concurrent writer (which would reintroduce the lost-write race this lock\n * closes).\n */\n private readonly lockStaleMs: number;\n private readonly lockMaxWaitMs: number;\n private readonly lockHeartbeatMs: number;\n\n /**\n * Sibling advisory lockfile: `<tombstones>.jsonl` → `<tombstones>.lock`.\n * Shared by append, revoke, and rebuild so every JSONL mutation serializes\n * against the others across processes (issue #1639: \"shared with rebuilds\").\n */\n private get lockPath(): string {\n return this.filePath.replace(/\\.jsonl$/i, \"\") + \".lock\";\n }\n\n /** Lazy load + build the in-memory index. Idempotent. */\n async load(): Promise<void> {\n if (this.loaded) return;\n if (this.loadPromise) return this.loadPromise;\n this.loadPromise = this.loadInternal();\n try {\n await this.loadPromise;\n } finally {\n this.loadPromise = null;\n }\n }\n\n private async loadInternal(migrateLegacy = true): Promise<void> {\n // Record the file mtime before reading so an ENOENT still records 0 and\n // a successful load does not immediately trigger a staleness reload.\n this.recordFileMtime();\n let raw: string;\n try {\n raw = await this.io.read(this.filePath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException)?.code;\n if (code !== \"ENOENT\") throw err;\n this.loaded = true;\n return;\n }\n const initial = this.parseEntries(raw);\n const migrated = migrateLegacy\n ? await this.migrateLegacyEntries(initial)\n : initial;\n this.resetIndex();\n for (const entry of migrated.entries) this.indexEntry(entry);\n this.corruptedLines = migrated.corruptedLines;\n this.loaded = true;\n }\n\n private parseEntries(raw: string): {\n entries: TombstoneEntry[];\n corruptedLines: number;\n } {\n const entries: TombstoneEntry[] = [];\n let corruptedLines = 0;\n for (const line of raw.split(\"\\n\")) {\n const entry = parseTombstoneLine(line);\n if (!entry) {\n if (line.trim().length > 0) corruptedLines += 1;\n continue;\n }\n entries.push(entry);\n }\n return { entries, corruptedLines };\n }\n\n /**\n * Re-index pre-Unicode records from retired source content.\n * Source reads stay bounded, but every batch finishes before the store\n * publishes its in-memory index. Missing sources remain eligible on restart.\n */\n private async migrateLegacyEntries(initial: {\n entries: TombstoneEntry[];\n corruptedLines: number;\n }): Promise<{ entries: TombstoneEntry[]; corruptedLines: number }> {\n const limit = this.options.legacyMigrationLimit ?? DEFAULT_LEGACY_MIGRATION_LIMIT;\n if (limit === 0 || !this.options.sourceContentsForMemoryIds) return initial;\n const sourceMemoryIds: string[] = [];\n const requested = new Set<string>();\n for (const entry of initial.entries) {\n if (\n entry.kind !== \"tombstone\" ||\n entry.normalizerVersion === TOMBSTONE_NORMALIZER_VERSION\n ) {\n continue;\n }\n if (requested.has(entry.sourceMemoryId)) continue;\n requested.add(entry.sourceMemoryId);\n sourceMemoryIds.push(entry.sourceMemoryId);\n }\n if (sourceMemoryIds.length === 0) return initial;\n const sourceContents = new Map<string, string | readonly string[]>();\n for (let offset = 0; offset < sourceMemoryIds.length; offset += limit) {\n const batch = sourceMemoryIds.slice(offset, offset + limit);\n const fetched = await this.options.sourceContentsForMemoryIds(batch);\n for (const [sourceMemoryId, content] of fetched) sourceContents.set(sourceMemoryId, content);\n }\n return await serializeMutations(`tombstone:${this.filePath}`, () =>\n this.withWriteLock(async () => {\n const latestRaw = await this.io.read(this.filePath);\n const latest = this.parseEntries(latestRaw);\n let changed = false;\n const migrateEntry = (entry: TombstoneEntry): TombstoneEntry => {\n if (\n entry.kind !== \"tombstone\" ||\n entry.normalizerVersion === TOMBSTONE_NORMALIZER_VERSION ||\n !requested.has(entry.sourceMemoryId)\n ) {\n return entry;\n }\n const resolved = sourceContents.get(entry.sourceMemoryId);\n if (resolved === undefined) return entry;\n const candidates = typeof resolved === \"string\" ? [resolved] : resolved;\n const matches = candidates.filter((source) =>\n entry.contentHash === this.options.hashContent(source) ||\n entry.contentHash === computeLegacyContentHash(source)\n );\n const explicitPrimary =\n matches.length === 0 &&\n entry.contentHash !== this.options.hashContent(entry.normalizedText);\n const source = matches[0] ?? (explicitPrimary ? candidates[0] : undefined);\n if (source === undefined) return entry;\n const currentHash = this.options.hashContent(source);\n const alias = explicitPrimary\n ? currentHash\n : matches\n .map((candidate) => this.options.hashContent(candidate))\n .find((hash) => hash !== currentHash);\n changed = true;\n return {\n ...entry,\n contentHash: explicitPrimary ? entry.contentHash : currentHash,\n ...(alias ? { currentContentHashAlias: alias } : {}),\n normalizedText: this.options.normalizeText(source),\n normalizerVersion: TOMBSTONE_NORMALIZER_VERSION,\n };\n };\n const serialized = latestRaw\n .split(\"\\n\")\n .map((line) => {\n const entry = parseTombstoneLine(line);\n if (!entry) return line;\n const migrated = migrateEntry(entry);\n return migrated === entry ? line : JSON.stringify(migrated);\n })\n .join(\"\\n\");\n if (!changed) return latest;\n await this.io.write(this.filePath, serialized);\n this.markWritten();\n return this.parseEntries(serialized);\n }),\n );\n }\n\n private resetIndex(): void {\n this.entries = [];\n this.byHash.clear();\n this.byNormalized.clear();\n this.byKey.clear();\n this.revokedIds.clear();\n this.byId.clear();\n }\n\n /**\n * Index an entry. Later entries (higher array index = newer createdAt)\n * OVERRIDE earlier ones at each tier key — the newest matching entry wins\n * (rule 25). Revocation entries mark their target as revoked.\n */\n private indexEntry(entry: TombstoneEntry): void {\n this.entries.push(entry);\n this.byId.set(entry.id, entry);\n if (entry.createdAt > (this.lastAppendAt ?? \"\")) {\n this.lastAppendAt = entry.createdAt;\n }\n if (entry.kind === \"revocation\") {\n if (entry.revokes) this.revokedIds.add(entry.revokes);\n return;\n }\n // Tombstone entries populate the lookup maps. The namespace is part of\n // every discriminator key (issue #1579 thread Ocs-O): when two\n // namespace-scoped stores share the same backing file, a later tombstone\n // for namespace B with identical content must NOT evict namespace A's map\n // entry — otherwise A's lookup finds B's id, rejects it on namespace\n // mismatch, and misses its own still-active tombstone (resurrection).\n const ns = entry.namespace;\n if (entry.normalizerVersion === TOMBSTONE_NORMALIZER_VERSION) {\n if (entry.contentHash) this.byHash.set(`${ns}\\0${entry.contentHash}`, entry.id);\n if (entry.currentContentHashAlias) {\n this.byHash.set(`${ns}\\0${entry.currentContentHashAlias}`, entry.id);\n }\n if (entry.normalizedText) this.byNormalized.set(`${ns}\\0${entry.normalizedText}`, entry.id);\n }\n if (entry.entityRef && entry.supersessionKey) {\n this.byKey.set(keyedTierKey(ns, entry.entityRef, entry.supersessionKey), entry.id);\n }\n }\n\n /** Invalidate the in-memory cache (rule 25). The next access reloads. */\n invalidate(): void {\n this.loaded = false;\n this.loadPromise = null;\n this.resetIndex();\n }\n\n /**\n * Cross-process staleness probe (#1579). If the file's mtime advanced since\n * the last load/own-write, a peer process appended and our in-memory index\n * is stale — invalidate and reload before the next access. Mutation callers\n * pass `migrate: false` to avoid nested serializer/lock acquisition.\n */\n async ensureFreshAgainstDisk(options: { migrate?: boolean } = {}): Promise<void> {\n if (!this.io.stat) return;\n let mtimeMs: number;\n try {\n mtimeMs = Math.floor(this.io.stat(this.filePath).mtimeMs);\n } catch {\n return; // ENOENT / permission — keep the loaded index (fail-open).\n }\n if (mtimeMs === this.fileMtimeMs && this.loaded) return;\n this.fileMtimeMs = mtimeMs;\n this.invalidate();\n if (options.migrate === false) {\n await this.loadInternal(false);\n } else {\n await this.load();\n }\n }\n\n /**\n * Record the file mtime after THIS process writes (append / revoke / rebuild)\n * so `ensureFreshAgainstDisk` does not treat our own write as a peer append\n * and throw away the just-updated in-memory index (#1579 — avoids a needless\n * invalidate+reload in the hot write path).\n */\n private markWritten(): void {\n this.recordFileMtime();\n }\n\n private recordFileMtime(): void {\n if (!this.io.stat) return;\n try {\n this.fileMtimeMs = Math.floor(this.io.stat(this.filePath).mtimeMs);\n } catch {\n // ENOENT — fresh store with no file yet; mtime stays at its current value.\n }\n }\n\n /**\n * Append a tombstone entry. Serialized via `serializeMutations` keyed by\n * file path so concurrent appends do not interleave, with rejection recovery\n * (rule 40 — a single failed append never poisons the chain). The in-memory\n * index is updated AFTER the durable append succeeds.\n *\n * Returns the new tombstone id.\n */\n async appendTombstone(input: {\n reason: TombstoneReason;\n createdBy: TombstoneCreatedBy;\n sourceMemoryId: string;\n rawContent: string;\n entityRef?: string;\n supersessionKey?: string;\n operationKey?: string;\n createdAt?: string;\n /**\n * Pre-computed canonical contentHash from the retired memory's frontmatter.\n * When provided, used directly so the tombstone's exact tier matches the\n * hash writeMemory computes on re-extraction (issue #1579 review: cited\n * facts must not slip past the chokepoint because the emitter hashed the\n * citation-annotated body instead of the canonical source).\n */\n contentHash?: string;\n }): Promise<string> {\n await this.load();\n const createdAt = input.createdAt ?? new Date().toISOString();\n const id = newTombstoneId();\n const currentHash = this.options.hashContent(input.rawContent);\n const currentNormalizedText = this.options.normalizeText(input.rawContent);\n const entry: TombstoneEntry = {\n id,\n ...(input.contentHash && input.contentHash !== currentHash\n ? { currentContentHashAlias: currentHash }\n : {}),\n kind: \"tombstone\",\n reason: input.reason,\n sourceMemoryId: input.sourceMemoryId,\n contentHash: input.contentHash ?? currentHash,\n normalizedText: currentNormalizedText,\n normalizerVersion: TOMBSTONE_NORMALIZER_VERSION,\n ...(input.entityRef ? { entityRef: input.entityRef } : {}),\n ...(input.supersessionKey ? { supersessionKey: input.supersessionKey } : {}),\n ...(input.operationKey ? { operationKey: input.operationKey } : {}),\n namespace: this.namespace,\n createdAt,\n createdBy: input.createdBy,\n };\n await this.serializeAppend(entry);\n this.indexEntry(entry);\n this.markWritten();\n await this.migrateLoadedLegacyEntries();\n return id;\n }\n\n /**\n * Append a revocation entry referencing `tombstoneId`. The log is\n * append-only; lookup treats a revoked tombstone as re-allowed (rule 25).\n */\n async revoke(tombstoneId: string, createdBy: TombstoneCreatedBy): Promise<string> {\n await this.load();\n const createdAt = new Date().toISOString();\n const id = newTombstoneId();\n const entry: TombstoneEntry = {\n id,\n kind: \"revocation\",\n reason: \"correction\",\n sourceMemoryId: \"\",\n contentHash: \"\",\n normalizedText: \"\",\n namespace: this.namespace,\n createdAt,\n createdBy,\n revokes: tombstoneId,\n };\n await this.serializeAppend(entry);\n this.indexEntry(entry);\n this.markWritten();\n await this.migrateLoadedLegacyEntries();\n return id;\n }\n\n private serializeAppend(entry: TombstoneEntry): Promise<void> {\n const line = JSON.stringify(entry) + \"\\n\";\n // serializeMutations (in-process, rule 40 rejection recovery) wraps the\n // cross-process lock: within one process appends are queued, and across\n // processes the advisory lockfile serializes the read-merge-write so two\n // Remnic processes appending concurrently cannot drop each other's entry\n // (issue #1639). Under the lock we re-sync the in-memory index against\n // disk first, so indexEntry builds on the peer's just-appended entries.\n return serializeMutations(`tombstone:${this.filePath}`, () =>\n this.withWriteLock(async () => {\n await this.ensureFreshAgainstDisk({ migrate: false });\n await this.io.append(this.filePath, line);\n }),\n );\n }\n\n private async migrateLoadedLegacyEntries(): Promise<void> {\n const initial = {\n entries: [...this.entries],\n corruptedLines: this.corruptedLines,\n };\n if (!initial.entries.some(\n (entry) => entry.kind === \"tombstone\" && entry.normalizerVersion !== TOMBSTONE_NORMALIZER_VERSION,\n )) {\n return;\n }\n try {\n const migrated = await this.migrateLegacyEntries(initial);\n this.resetIndex();\n for (const entry of migrated.entries) this.indexEntry(entry);\n this.corruptedLines = migrated.corruptedLines;\n this.loaded = true;\n } catch {\n // The durable mutation already succeeded; defer migration to next load.\n }\n }\n\n /**\n * Acquire the cross-process tombstone write lock and run `task` under it\n * (issue #1639). Strict-fail on acquisition timeout: the secure-store append\n * is a read-merge-write, so a best-effort unlocked run would clobber a\n * concurrent writer — reintroducing the lost-write race this lock closes.\n * The thrown error surfaces to the caller (rule 34: never silently drop);\n * rebuild recovers the tombstone on the next maintenance cycle.\n *\n * In-process callers are already serialized by serializeMutations (one key\n * for append/revoke/rebuild), so this lock only contends across processes —\n * the single-process daemon (default deployment) acquires it immediately.\n */\n private withWriteLock<T>(task: () => Promise<T>): Promise<T> {\n return withHeldFileLock(\n this.lockPath,\n {\n staleMs: this.lockStaleMs,\n maxWaitMs: this.lockMaxWaitMs,\n heartbeatMs: this.lockHeartbeatMs,\n },\n async (acquired) => {\n if (!acquired) {\n throw new Error(\n \"could not acquire tombstone write lock (contention timeout or filesystem error)\",\n );\n }\n return task();\n },\n );\n }\n\n /**\n * Look up whether `query` is blocked by an active (non-revoked) tombstone.\n * Tiers are checked in order: exact (contentHash) → normalized → keyed →\n * semantic (off by default). Returns the first active match, or `null`.\n *\n * Namespace isolation (rule 42): only entries with `namespace === query.namespace`\n * match. The store is per-namespace, so this is belt-and-suspenders.\n */\n lookup(query: TombstoneLookupQuery): TombstoneMatch | null {\n // We intentionally do NOT await load() here — lookup is called from the\n // hot write path. Callers MUST ensure the store is loaded before lookup\n // (StorageManager does this in ensureTombstoneStoreLoaded). If not loaded,\n // lookup returns null (fail-open: a missing tombstone check is preferable\n // to crashing every write — see rule 34 / the \"degrade gracefully\" note).\n if (!this.options.enabled) return null;\n if (!this.loaded) return null;\n\n // Tier 1: exact contentHash. Namespace is part of the map key (thread\n // Ocs-O), so the lookup finds only this namespace's tombstone even when\n // the backing file is shared. The namespace equality check below is kept\n // as defense-in-depth.\n const ns = query.namespace;\n if (query.contentHash) {\n const id = this.byHash.get(`${ns}\\0${query.contentHash}`);\n if (id && !this.revokedIds.has(id)) {\n const entry = this.byId.get(id);\n if (entry && entry.namespace === ns) {\n return { tombstoneId: id, matchedTier: \"exact\", reason: entry.reason };\n }\n }\n }\n // Tier 2: normalized text.\n if (query.normalizedText) {\n const id = this.byNormalized.get(`${ns}\\0${query.normalizedText}`);\n if (id && !this.revokedIds.has(id)) {\n const entry = this.byId.get(id);\n if (entry && entry.namespace === ns) {\n return { tombstoneId: id, matchedTier: \"normalized\", reason: entry.reason };\n }\n }\n }\n // Tier 3: keyed (entityRef + supersessionKey). Issue #1579 thread\n // Ociag/Oci-W: check EVERY supplied key, not just the first — emitters\n // append one tombstone per matched supersession key, so the active block\n // can live on any later key. The union of `supersessionKey` (singular,\n // direct callers) and `supersessionKeys` (array, write chokepoint) is\n // checked; the first active match wins (tiers are equality-based, so\n // ordering across keys does not affect correctness).\n if (query.entityRef) {\n const keysToCheck: string[] = [];\n if (query.supersessionKey) keysToCheck.push(query.supersessionKey);\n if (query.supersessionKeys) {\n for (const k of query.supersessionKeys) {\n if (!keysToCheck.includes(k)) keysToCheck.push(k);\n }\n }\n for (const key of keysToCheck) {\n const id = this.byKey.get(keyedTierKey(ns, query.entityRef, key));\n if (id && !this.revokedIds.has(id)) {\n const entry = this.byId.get(id);\n if (entry && entry.namespace === ns) {\n return { tombstoneId: id, matchedTier: \"keyed\", reason: entry.reason };\n }\n }\n }\n }\n // Tier 4: semantic (off by default, rule 48).\n if (this.options.semanticMatch && this.options.semanticSimilarity && query.normalizedText) {\n const threshold = this.options.semanticThreshold;\n let best: { id: string; reason: TombstoneReason; score: number } | null = null;\n for (const entry of this.entries) {\n if (entry.kind !== \"tombstone\") continue;\n if (entry.normalizerVersion !== TOMBSTONE_NORMALIZER_VERSION) continue;\n if (entry.namespace !== query.namespace) continue;\n if (this.revokedIds.has(entry.id)) continue;\n if (!entry.normalizedText) continue;\n const score = this.options.semanticSimilarity(query.normalizedText, entry.normalizedText);\n if (score >= threshold && (!best || score > best.score)) {\n best = { id: entry.id, reason: entry.reason, score };\n }\n }\n if (best) {\n return { tombstoneId: best.id, matchedTier: \"semantic\", reason: best.reason };\n }\n }\n return null;\n }\n async hasExactEntry(input: {\n sourceMemoryId: string;\n contentHash?: string;\n entityRef?: string;\n supersessionKey?: string;\n createdAt?: string;\n operationKey?: string;\n }): Promise<boolean> {\n if (!this.options.enabled) return false;\n await this.ensureFreshAgainstDisk();\n await this.load();\n return this.entries.some(\n (entry) =>\n entry.kind === \"tombstone\" &&\n !this.revokedIds.has(entry.id) &&\n entry.namespace === this.namespace &&\n entry.sourceMemoryId === input.sourceMemoryId &&\n (input.contentHash === undefined || entry.contentHash === input.contentHash) &&\n (input.entityRef === undefined || entry.entityRef === input.entityRef) &&\n (input.supersessionKey === undefined || entry.supersessionKey === input.supersessionKey) &&\n (input.createdAt === undefined || entry.createdAt === input.createdAt) &&\n (input.operationKey === undefined || entry.operationKey === input.operationKey),\n );\n }\n\n\n /** Aggregate stats for the doctor / x-ray surfaces. */\n stats(): TombstoneStats {\n let active = 0;\n for (const entry of this.entries) {\n if (entry.kind === \"tombstone\" && !this.revokedIds.has(entry.id)) active += 1;\n }\n return {\n count: active,\n revoked: this.revokedIds.size,\n lastAppendAt: this.lastAppendAt,\n corruptedLines: this.corruptedLines,\n loaded: this.loaded,\n };\n }\n\n /** Read-only snapshot of all entries (for rebuild + tests). */\n snapshot(): readonly TombstoneEntry[] {\n return this.entries;\n }\n\n /**\n * Rebuild the in-memory index + JSONL from the supplied retired-memory\n * records + existing entries (preserving revocations). Byte-stable: entries\n * are sorted by (createdAt, id) before write (rule 38).\n *\n * Returns the count of tombstone entries written.\n */\n async rebuild(retiredMemories: ReadonlyArray<RetiredMemoryRecord>): Promise<number> {\n // The full read-merge-write runs UNDER the cross-process lock (issue #1639,\n // cursor/codex review): we ensureFreshAgainstDisk() first so the in-memory\n // index reflects any peer append/revoke that landed while we waited for the\n // lock, THEN compute the payload. Rebuild rewrites the entire JSONL, so a\n // payload built from a stale this.entries would overwrite a peer's just-\n // written entry and resurrect a retired fact — the exact invariant this\n // store exists to enforce. serializeMutations (in-process) wraps the\n // cross-process lock; the key is unified with append/revoke so they cannot\n // interleave in-process either.\n const rebuiltCount = await serializeMutations(`tombstone:${this.filePath}`, () =>\n this.withWriteLock(async () => {\n await this.ensureFreshAgainstDisk({ migrate: false });\n // Preserve existing revocations (all namespaces — ids are globally\n // unique) so a rebuild does not silently un-revoke.\n const existingRevocations = this.entries.filter((e) => e.kind === \"revocation\");\n // Preserve tombstone entries from OTHER namespaces when the backing\n // file is shared (issue #1579 thread Oc2MJ). rebuild rewrites the\n // entire file; without preserving foreign entries, rebuilding\n // namespace A would silently delete namespace B's tombstones, allowing\n // resurrection in B.\n const foreignTombstones = this.entries.filter(\n (e) => e.kind === \"tombstone\" && e.namespace !== this.namespace,\n );\n // Reuse existing tombstone ids for source-equivalent entries so a prior\n // revocation (which references the tombstone id) survives rebuild —\n // minting fresh ids would orphan the revocation and silently un-revoke.\n // Issue #1579 thread Oci-T: key the reuse map by (sourceMemoryId,\n // supersessionKey). See the append path above for the full rationale.\n const existingBySource = new Map<string, string>();\n for (const e of this.entries) {\n if (e.kind === \"tombstone\") {\n existingBySource.set(`${e.sourceMemoryId}\\u{0000}${e.supersessionKey ?? \"\"}`, e.id);\n }\n }\n const rebuilt: TombstoneEntry[] = retiredMemories.map((m) => {\n const currentHash = this.options.hashContent(m.rawContent);\n const currentNormalizedText = this.options.normalizeText(m.rawContent);\n const persistedHash = m.contentHash;\n // A persisted hash equal to the body's LEGACY hash only proves the\n // record predates the Unicode normalizer when that legacy hash is\n // unambiguous. When the legacy normalizer is lossy for this body\n // (any body whose ASCII skeleton collides with a distinct\n // contentHashSource), the equality cannot distinguish \"old body\n // hash\" from \"explicit source identity\" — replacing the persisted\n // hash would displace a live identity (issue #2367). Preserving\n // keeps BOTH keys: contentHash stays the persisted identity and\n // currentContentHashAlias still blocks the body.\n\n // Repair only when the persisted hash provably identifies THIS\n // body's stale legacy hash: either the unambiguous case (legacy and\n // current normalizations agree), or the empty-skeleton case — every\n // non-ASCII-only body normalizes to the empty legacy skeleton, so a\n // persisted hash equal to hash(\"\") is the shared non-identifying\n // legacy body hash and publishing it on the exact tier would\n // collide unrelated tombstones. Any OTHER persisted hash on an\n // empty-skeleton body is a distinct explicit identity (e.g.\n // contentHashSource) and must be preserved.\n const legacyBodyHash = computeLegacyContentHash(m.rawContent);\n const repairEmptySkeleton =\n normalizeLegacyContent(m.rawContent).length === 0 && persistedHash === legacyBodyHash;\n const preserveOverride =\n persistedHash !== undefined &&\n persistedHash !== currentHash &&\n !repairEmptySkeleton &&\n !isUnambiguousLegacyContentHash(m.rawContent, persistedHash, currentNormalizedText);\n return {\n id:\n existingBySource.get(`${m.memoryId}\\u{0000}${m.supersessionKey ?? \"\"}`) ??\n newTombstoneId(),\n ...(preserveOverride ? { currentContentHashAlias: currentHash } : {}),\n kind: \"tombstone\" as const,\n reason: m.reason,\n sourceMemoryId: m.memoryId,\n contentHash: preserveOverride ? persistedHash : currentHash,\n normalizedText: currentNormalizedText,\n normalizerVersion: TOMBSTONE_NORMALIZER_VERSION,\n ...(m.entityRef ? { entityRef: m.entityRef } : {}),\n ...(m.supersessionKey ? { supersessionKey: m.supersessionKey } : {}),\n namespace: this.namespace,\n createdAt: m.createdAt,\n createdBy: m.createdBy,\n };\n });\n // Sort deterministically (rule 38): createdAt, then id for stability.\n rebuilt.sort((a, b) =>\n a.createdAt === b.createdAt\n ? a.id < b.id ? -1 : a.id > b.id ? 1 : 0\n : a.createdAt < b.createdAt ? -1 : 1,\n );\n const all = [...rebuilt, ...existingRevocations, ...foreignTombstones].sort((a, b) =>\n a.createdAt === b.createdAt\n ? a.id < b.id ? -1 : a.id > b.id ? 1 : 0\n : a.createdAt < b.createdAt ? -1 : 1,\n );\n const serialized =\n all.map((e) => JSON.stringify(e)).join(\"\\n\") + (all.length > 0 ? \"\\n\" : \"\");\n await this.io.write(this.filePath, serialized);\n // Update the in-memory index under the same lock so it stays consistent\n // with the file we just wrote (no window for a lookup to see a stale\n // index that misses a just-rebuilt entry).\n this.resetIndex();\n for (const entry of all) this.indexEntry(entry);\n this.corruptedLines = 0;\n this.loaded = true;\n this.markWritten();\n return rebuilt.length;\n }),\n );\n await this.migrateLoadedLegacyEntries();\n return rebuiltCount;\n }\n}\n\n/** A retired memory projected into the shape `TombstoneStore.rebuild` consumes. */\nexport interface RetiredMemoryRecord {\n memoryId: string;\n rawContent: string;\n entityRef?: string;\n supersessionKey?: string;\n reason: TombstoneReason;\n createdBy: TombstoneCreatedBy;\n createdAt: string;\n /** Canonical contentHash from the retired memory's frontmatter (#1579). */\n contentHash?: string;\n}\n\n/**\n * Project a corpus of memories into the retired-memory records `rebuild`\n * consumes. Pure (no I/O) so the StorageManager wiring stays thin (#1579,\n * #1520 god-file ratchet). Only superseded / forgotten / rejected FACTS\n * participate — entities, questions, and artifacts have their own lifecycle\n * (issue pitfall). The supersession key is derived from structured attributes\n * via the injected helper so there is one keyed-tier definition (rule 23).\n */\nexport function collectRetiredMemoriesForRebuild(\n memories: ReadonlyArray<{\n frontmatter: {\n id: string;\n status?: string;\n category?: string;\n contentHash?: string;\n entityRef?: string;\n structuredAttributes?: Record<string, string>;\n updated?: string;\n created?: string;\n };\n content: string;\n }>,\n deps: {\n /** Strip citation annotations from the body before hashing/normalizing. */\n stripCitation: (text: string) => string;\n /** Derive the keyed-tier supersession key (one helper, rule 23). */\n supersessionKeysForFact: (spec: {\n entityRef?: string;\n structuredAttributes?: Record<string, string>;\n }) => string[];\n },\n): RetiredMemoryRecord[] {\n const retired: RetiredMemoryRecord[] = [];\n for (const m of memories) {\n const status = m.frontmatter.status;\n if (status !== \"superseded\" && status !== \"rejected\" && status !== \"forgotten\") continue;\n if (m.frontmatter.category !== \"fact\") continue;\n const reason: TombstoneReason =\n status === \"superseded\" ? \"supersession\" : status === \"forgotten\" ? \"retraction\" : \"correction\";\n const createdBy: TombstoneCreatedBy =\n reason === \"supersession\" ? \"supersession\" : \"user_correction\";\n const entityRef = m.frontmatter.entityRef;\n const keys =\n entityRef && m.frontmatter.structuredAttributes\n ? deps.supersessionKeysForFact({\n entityRef,\n structuredAttributes: m.frontmatter.structuredAttributes,\n })\n : [];\n // Issue #1579 thread Ocgjz: emit one record per matched supersession key\n // (not just keys[0]) so rebuild reproduces the same keyed tombstones as\n // live temporal-supersession (which now appends one per key — thread ObteS).\n // Without this, a rebuild would under-rebuild the JSONL and keyed-tier\n // blocks would disappear until rediscovered.\n const keysToEmit = keys.length > 0 ? keys : [undefined];\n for (const key of keysToEmit) {\n retired.push({\n memoryId: m.frontmatter.id,\n rawContent: deps.stripCitation(m.content),\n contentHash: m.frontmatter.contentHash,\n ...(entityRef ? { entityRef } : {}),\n ...(key ? { supersessionKey: key } : {}),\n reason,\n createdBy,\n createdAt: m.frontmatter.updated || m.frontmatter.created || new Date().toISOString(),\n });\n }\n }\n return retired;\n}\n\n/**\n * One-shot write-time resurrection gate (issue #1579 / #2213). Looks up the\n * fact's identity in the tombstone store and, on a match, downgrades the\n * frontmatter to `pending_review` + `blockedBy` IN PLACE. ADD-ONLY: an\n * already-blocked or terminal-status record is left untouched. Pure over its\n * inputs (no I/O beyond the injected store) so both `writeMemory`'s gate and\n * the chunk-repair re-gate share one lookup + apply.\n */\nexport function applyTombstoneResurrectionGate(\n store: Pick<TombstoneStore, \"lookup\">,\n fm: {\n id: string;\n status?: string;\n blockedBy?: string;\n tombstoneBlockTier?: TombstoneMatchTier;\n entityRef?: string;\n contentHash?: string;\n },\n query: {\n normalizedText: string;\n supersessionKeys: string[];\n namespace: string;\n },\n): TombstoneMatch | null {\n if (fm.status === \"pending_review\" && fm.blockedBy) return null;\n if (!(fm.status === undefined || fm.status === \"active\" || fm.status === \"pending_review\")) return null;\n const match = store.lookup({\n contentHash: fm.contentHash,\n normalizedText: query.normalizedText,\n ...(fm.entityRef ? { entityRef: fm.entityRef } : {}),\n ...(query.supersessionKeys.length > 0 ? { supersessionKeys: query.supersessionKeys } : {}),\n namespace: query.namespace,\n });\n if (!match) return null;\n fm.status = \"pending_review\";\n fm.blockedBy = match.tombstoneId;\n fm.tombstoneBlockTier = match.matchedTier;\n return match;\n}\n\n/**\n * Build the live-emission tombstone inputs for a single retired FACT — one\n * input per derived supersession key (or a single keyless record when no\n * structured attributes are present). Pure (no I/O) so the emitters in\n * `StorageManager.supersedeMemory` (contradiction) and `forgetMemory`\n * (retraction) stay thin (#1579, #1520 god-file ratchet). Mirrors the\n * temporal-supersession emitter and `collectRetiredMemoriesForRebuild` so\n * every retire path emits the same keyed-tombstone shape (issue #1579\n * threads Oci-Y / OchiF: without per-key tombstones, a paraphrased\n * re-observation missed the keyed tier and the fact resurrected active).\n */\nexport function buildRetiredFactTombstoneInputs(\n memory: {\n id: string;\n content: string;\n contentHash?: string;\n entityRef?: string;\n structuredAttributes?: Record<string, string>;\n },\n opts: {\n reason: TombstoneReason;\n createdBy: TombstoneCreatedBy;\n createdAt: string;\n supersessionKeysForFact: (spec: {\n entityRef?: string;\n structuredAttributes?: Record<string, string>;\n }) => string[];\n },\n): Array<{\n reason: TombstoneReason;\n createdBy: TombstoneCreatedBy;\n sourceMemoryId: string;\n rawContent: string;\n contentHash?: string;\n entityRef?: string;\n supersessionKey?: string;\n createdAt: string;\n}> {\n const keys =\n memory.entityRef && memory.structuredAttributes\n ? opts.supersessionKeysForFact({\n entityRef: memory.entityRef,\n structuredAttributes: memory.structuredAttributes,\n })\n : [];\n const keysToEmit = keys.length > 0 ? keys : [undefined];\n return keysToEmit.map((key) => ({\n reason: opts.reason,\n createdBy: opts.createdBy,\n sourceMemoryId: memory.id,\n rawContent: memory.content,\n ...(memory.contentHash ? { contentHash: memory.contentHash } : {}),\n ...(memory.entityRef ? { entityRef: memory.entityRef } : {}),\n ...(key ? { supersessionKey: key } : {}),\n createdAt: opts.createdAt,\n }));\n}\n"],"mappings":"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","names":["source"]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/user-message-cleaning.ts
|
|
2
|
+
var NO_PLATFORM_HEADER = /$a/;
|
|
3
|
+
var WRAPPER_OPEN = "<supermemory-context";
|
|
4
|
+
var WRAPPER_CLOSE = "</supermemory-context>";
|
|
5
|
+
var WRAPPER_MAX_ATTRIBUTE_CHARS = 256;
|
|
6
|
+
function isWhitespaceCode(code) {
|
|
7
|
+
return code === 32 || code >= 9 && code <= 13;
|
|
8
|
+
}
|
|
9
|
+
function stripMemoryWrappers(content) {
|
|
10
|
+
let out = "";
|
|
11
|
+
let cursor = 0;
|
|
12
|
+
for (; ; ) {
|
|
13
|
+
const open = content.indexOf(WRAPPER_OPEN, cursor);
|
|
14
|
+
if (open === -1) return out + content.slice(cursor);
|
|
15
|
+
const headEnd = content.indexOf(">", open);
|
|
16
|
+
if (headEnd === -1) return out + content.slice(cursor);
|
|
17
|
+
const head = content.slice(open + WRAPPER_OPEN.length, headEnd);
|
|
18
|
+
const headIsPlain = head.length > 0 && (head.length > WRAPPER_MAX_ATTRIBUTE_CHARS + 1 || headIsNotAttributeRun(head));
|
|
19
|
+
if (head !== "" && headIsPlain) {
|
|
20
|
+
out += content.slice(cursor, open + WRAPPER_OPEN.length);
|
|
21
|
+
cursor = open + WRAPPER_OPEN.length;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const close = content.indexOf(WRAPPER_CLOSE, headEnd);
|
|
25
|
+
if (close === -1) return out + content.slice(cursor);
|
|
26
|
+
let after = close + WRAPPER_CLOSE.length;
|
|
27
|
+
while (after < content.length && isWhitespaceCode(content.charCodeAt(after))) {
|
|
28
|
+
after += 1;
|
|
29
|
+
}
|
|
30
|
+
out += content.slice(cursor, open);
|
|
31
|
+
cursor = after;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function stripTrailingMessageId(content) {
|
|
35
|
+
const marker = "[message_id:";
|
|
36
|
+
const start = content.lastIndexOf(marker);
|
|
37
|
+
if (start === -1) return null;
|
|
38
|
+
let index = start + marker.length;
|
|
39
|
+
while (index < content.length && isWhitespaceCode(content.charCodeAt(index))) {
|
|
40
|
+
index += 1;
|
|
41
|
+
}
|
|
42
|
+
const idStart = index;
|
|
43
|
+
while (index < content.length && content.charCodeAt(index) !== 93) {
|
|
44
|
+
index += 1;
|
|
45
|
+
}
|
|
46
|
+
if (index === idStart || index === content.length) return null;
|
|
47
|
+
index += 1;
|
|
48
|
+
while (index < content.length && isWhitespaceCode(content.charCodeAt(index))) {
|
|
49
|
+
index += 1;
|
|
50
|
+
}
|
|
51
|
+
if (index !== content.length) return null;
|
|
52
|
+
let boundary = start;
|
|
53
|
+
while (boundary > 0 && isWhitespaceCode(content.charCodeAt(boundary - 1))) {
|
|
54
|
+
boundary -= 1;
|
|
55
|
+
}
|
|
56
|
+
return content.slice(0, boundary);
|
|
57
|
+
}
|
|
58
|
+
function headIsNotAttributeRun(head) {
|
|
59
|
+
if (head.charCodeAt(0) !== 32 && !(head.charCodeAt(0) >= 9 && head.charCodeAt(0) <= 13)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
for (let index = 0; index < head.length; index += 1) {
|
|
63
|
+
const code = head.charCodeAt(index);
|
|
64
|
+
if (code === 60 || code === 62) return true;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
function cleanUserMessageWithPattern(content, platformHeaderPattern) {
|
|
69
|
+
let cleaned = stripMemoryWrappers(content);
|
|
70
|
+
const platformHeader = cleaned.match(platformHeaderPattern);
|
|
71
|
+
const hasPlatformHeader = platformHeader !== null;
|
|
72
|
+
if (platformHeader) {
|
|
73
|
+
cleaned = cleaned.slice(platformHeader[0].length);
|
|
74
|
+
}
|
|
75
|
+
cleaned = cleaned.replace(
|
|
76
|
+
/^\s*## Memory Context \((?:Engram|Remnic)\)[\s\S]*?(?=\n## |\n$)/i,
|
|
77
|
+
""
|
|
78
|
+
);
|
|
79
|
+
if (hasPlatformHeader) {
|
|
80
|
+
cleaned = stripTrailingMessageId(cleaned) ?? cleaned;
|
|
81
|
+
}
|
|
82
|
+
return cleaned.trim();
|
|
83
|
+
}
|
|
84
|
+
function cleanArchivedUserMessage(content) {
|
|
85
|
+
return cleanUserMessageWithPattern(content, NO_PLATFORM_HEADER);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export {
|
|
89
|
+
cleanUserMessageWithPattern,
|
|
90
|
+
cleanArchivedUserMessage
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=chunk-47DU4SGJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/user-message-cleaning.ts"],"sourcesContent":["/**\n * Host-agnostic user-message cleaning (issue #2331).\n *\n * Owns the generic part of the cleaner the OpenClaw wiring has always used\n * (`src/user-message-cleaning.ts` in the root host bundle): stripping the\n * structured host-injected memory wrappers and the leading memory-context\n * preamble from a user message. The host wrapper keeps only the\n * platform-header pattern (channel envelopes are an OpenClaw concept) and\n * delegates here, so core consumers — the episodic-context recall section\n * re-rendering archived user turns — share ONE implementation instead of a\n * second cleaner drifting beside it.\n */\n\n/** Never-matching header pattern for callers with no platform envelope. */\nconst NO_PLATFORM_HEADER = /$a/;\n\nconst WRAPPER_OPEN = \"<supermemory-context\";\nconst WRAPPER_CLOSE = \"</supermemory-context>\";\nconst WRAPPER_MAX_ATTRIBUTE_CHARS = 256;\n\nfunction isWhitespaceCode(code: number): boolean {\n return code === 32 || (code >= 9 && code <= 13);\n}\n\n/**\n * Remove `<supermemory-context …>…</supermemory-context>` wrappers. A\n * single left-to-right scan with string searches — no regex on uncontrolled\n * input — so adversarial repeats of the tag literal stay linear (CodeQL\n * redos rule, issue #2331 review). Malformed or oversized tag heads are\n * treated as plain text, and an unterminated wrapper preserves the rest.\n */\nfunction stripMemoryWrappers(content: string): string {\n let out = \"\";\n let cursor = 0;\n for (;;) {\n const open = content.indexOf(WRAPPER_OPEN, cursor);\n if (open === -1) return out + content.slice(cursor);\n const headEnd = content.indexOf(\">\", open);\n if (headEnd === -1) return out + content.slice(cursor);\n const head = content.slice(open + WRAPPER_OPEN.length, headEnd);\n const headIsPlain =\n head.length > 0 &&\n (head.length > WRAPPER_MAX_ATTRIBUTE_CHARS + 1 || headIsNotAttributeRun(head));\n if (head !== \"\" && headIsPlain) {\n // Not a wrapper open tag: keep the literal and continue after it.\n out += content.slice(cursor, open + WRAPPER_OPEN.length);\n cursor = open + WRAPPER_OPEN.length;\n continue;\n }\n const close = content.indexOf(WRAPPER_CLOSE, headEnd);\n if (close === -1) return out + content.slice(cursor);\n let after = close + WRAPPER_CLOSE.length;\n while (after < content.length && isWhitespaceCode(content.charCodeAt(after))) {\n after += 1;\n }\n // Keep everything before the wrapper; only the wrapper (plus its\n // trailing whitespace) is removed.\n out += content.slice(cursor, open);\n cursor = after;\n }\n}\n\n/**\n * Remove a trailing `[message_id: …]` marker (with surrounding whitespace)\n * using a single right-anchored string scan — no regex on uncontrolled\n * input (CodeQL redos rule). Returns null when no marker terminates the\n * content, leaving the caller's string untouched.\n */\nfunction stripTrailingMessageId(content: string): string | null {\n const marker = \"[message_id:\";\n const start = content.lastIndexOf(marker);\n if (start === -1) return null;\n let index = start + marker.length;\n while (index < content.length && isWhitespaceCode(content.charCodeAt(index))) {\n index += 1;\n }\n const idStart = index;\n while (index < content.length && content.charCodeAt(index) !== 93 /* ] */) {\n index += 1;\n }\n if (index === idStart || index === content.length) return null;\n index += 1; // past the closing bracket\n while (index < content.length && isWhitespaceCode(content.charCodeAt(index))) {\n index += 1;\n }\n if (index !== content.length) return null;\n let boundary = start;\n while (boundary > 0 && isWhitespaceCode(content.charCodeAt(boundary - 1))) {\n boundary -= 1;\n }\n return content.slice(0, boundary);\n}\n\n/** True when the tag-head text cannot be a whitespace-led attribute run. */\nfunction headIsNotAttributeRun(head: string): boolean {\n if (head.charCodeAt(0) !== 32 && !(head.charCodeAt(0) >= 9 && head.charCodeAt(0) <= 13)) {\n return true;\n }\n for (let index = 0; index < head.length; index += 1) {\n const code = head.charCodeAt(index);\n if (code === 60 || code === 62) return true;\n }\n return false;\n}\n\nexport function cleanUserMessageWithPattern(\n content: string,\n platformHeaderPattern: RegExp,\n): string {\n let cleaned = stripMemoryWrappers(content);\n const platformHeader = cleaned.match(platformHeaderPattern);\n const hasPlatformHeader = platformHeader !== null;\n if (platformHeader) {\n cleaned = cleaned.slice(platformHeader[0].length);\n }\n\n // Remove markdown memory context only when it is a leading preamble. If a\n // user writes a section with this title later in their message, preserve it.\n cleaned = cleaned.replace(\n /^\\s*## Memory Context \\((?:Engram|Remnic)\\)[\\s\\S]*?(?=\\n## |\\n$)/i,\n \"\",\n );\n\n if (hasPlatformHeader) {\n cleaned = stripTrailingMessageId(cleaned) ?? cleaned;\n }\n return cleaned.trim();\n}\n\n/**\n * Clean an archived user turn for re-injection (issue #2331): strips the\n * memory wrappers this system itself injects, so an archived echo of a\n * previous recall output cannot re-enter the context through the\n * episodic-context section. No platform envelope stripping — core has no\n * host channel-envelope concept.\n */\nexport function cleanArchivedUserMessage(content: string): string {\n return cleanUserMessageWithPattern(content, NO_PLATFORM_HEADER);\n}\n"],"mappings":"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","names":[]}
|