@remnic/core 9.66.0 → 9.66.1
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 +22 -22
- package/dist/access-authorization-probe.d.ts +11 -11
- package/dist/access-authorization-probe.js +23 -23
- package/dist/access-boundary.d.ts +11 -11
- package/dist/access-boundary.js +22 -22
- package/dist/access-cli.js +86 -84
- 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 +22 -22
- 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.d.ts +2 -2
- package/dist/access-http-query.js +24 -24
- package/dist/access-http.d.ts +12 -12
- package/dist/access-http.js +39 -39
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +22 -22
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +22 -22
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +29 -29
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-CLWUoMyW.d.ts → access-namespace-preflight-50VIkPhB.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +22 -22
- package/dist/access-observe-write-surface.d.ts +11 -11
- package/dist/access-observe-write-surface.js +22 -22
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-operations-batch.js +24 -24
- package/dist/access-operations.d.ts +16 -16
- package/dist/access-operations.js +28 -28
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +22 -22
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +22 -22
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +22 -22
- package/dist/access-schema.d.ts +89 -89
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-CEUE1Isj.d.ts → access-service-C2tV2-uL.d.ts} +65 -65
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +22 -22
- package/dist/access-surface-catalog.d.ts +11 -11
- package/dist/access-surface-catalog.js +24 -24
- 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 +2 -2
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +9 -9
- 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-D1HgugTA.d.ts → catalog-C2jA-gLm.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +10 -10
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-J3OND5QT.js → chunk-2FA7U5XY.js} +2 -2
- package/dist/{chunk-GEJKYA7D.js → chunk-2ITZ74A6.js} +9 -9
- package/dist/{chunk-2LBAFHOQ.js → chunk-2X6BGKQL.js} +8 -8
- package/dist/{chunk-KODXCHXJ.js → chunk-46XR5FNZ.js} +39 -3
- package/dist/chunk-46XR5FNZ.js.map +1 -0
- package/dist/{chunk-4STAANV7.js → chunk-4XLTUR6R.js} +3 -3
- package/dist/{chunk-FTTJRVB7.js → chunk-65JOGLIS.js} +2 -2
- package/dist/{chunk-FESUGFIL.js → chunk-7UOXCCCI.js} +2 -2
- package/dist/{chunk-PEBH5DCK.js → chunk-AF5H7TKI.js} +100 -18
- package/dist/chunk-AF5H7TKI.js.map +1 -0
- package/dist/{chunk-6CEGSTBD.js → chunk-B4AOWRYF.js} +4 -4
- package/dist/{chunk-FYWLSFFS.js → chunk-C5IUOBCN.js} +2 -2
- package/dist/{chunk-FKKGCGYL.js → chunk-CHGG74CY.js} +2 -2
- package/dist/{chunk-H7VDIF2V.js → chunk-CX4OLNIH.js} +2 -2
- package/dist/{chunk-Z3YEGSR4.js → chunk-D3UXGE5D.js} +10 -10
- package/dist/{chunk-7XOG75AU.js → chunk-D6Q5EPOV.js} +2 -2
- package/dist/{chunk-MJRGVXPQ.js → chunk-EH65UV2Z.js} +2 -2
- package/dist/{chunk-VQ4AMTGZ.js → chunk-EWKVYCFP.js} +1 -1
- package/dist/{chunk-23CVL7HS.js → chunk-FFUMTH27.js} +2 -2
- package/dist/{chunk-GX6FTSYH.js → chunk-GAJK3DQ5.js} +2 -2
- package/dist/{chunk-O57GM3FR.js → chunk-GBEOUCBB.js} +2 -2
- package/dist/{chunk-DMEHOEC7.js → chunk-H2IRSXZN.js} +3 -3
- package/dist/{chunk-CFVTRUR3.js → chunk-H6RSANGQ.js} +2 -2
- package/dist/chunk-HVAEXYPL.js +98 -0
- package/dist/chunk-HVAEXYPL.js.map +1 -0
- package/dist/{chunk-OAJMQKQR.js → chunk-IGZCAHFL.js} +2 -2
- package/dist/{chunk-CN4VKV3S.js → chunk-INUBU6I5.js} +2 -2
- package/dist/{chunk-CTCGHNWN.js → chunk-J2R275FN.js} +4 -4
- package/dist/{chunk-2QSZNTDO.js → chunk-JBPKEARU.js} +7 -7
- package/dist/{chunk-VQNRICAQ.js → chunk-JKTV3JNX.js} +3 -3
- package/dist/{chunk-33MFRY25.js → chunk-KI64TTBL.js} +2 -2
- package/dist/{chunk-VCKWULAK.js → chunk-KJXCD7VR.js} +5 -5
- package/dist/{chunk-7LCGFUMB.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-GSKINLAK.js → chunk-LJABGXC4.js} +3 -3
- package/dist/{chunk-NPIBN2VL.js → chunk-LK4TOYPU.js} +2 -2
- package/dist/{chunk-EZSCW4EM.js → chunk-LYUUA6QB.js} +2 -2
- package/dist/{chunk-I5VB44ZK.js → chunk-M5ERTI4I.js} +2 -2
- package/dist/{chunk-IHGMRDEE.js → chunk-MUEGIKKY.js} +227 -144
- package/dist/chunk-MUEGIKKY.js.map +1 -0
- package/dist/{chunk-QCRJMU5V.js → chunk-NFP4KPTA.js} +2 -2
- package/dist/{chunk-YXFCALVT.js → chunk-NSTNGMSS.js} +8 -8
- package/dist/{chunk-L4X4PJYK.js → chunk-NUF7VSEX.js} +2 -2
- package/dist/{chunk-IVIAHQBR.js → chunk-OJUEUQDJ.js} +2 -2
- package/dist/{chunk-ZW4VXELZ.js → chunk-OMX6TKXH.js} +2 -2
- package/dist/{chunk-EFQCDJZ2.js → chunk-QBNE55VA.js} +2 -2
- package/dist/{chunk-6QDXA26G.js → chunk-RPIS5FQ7.js} +47 -47
- package/dist/{chunk-HJXA6ZM7.js → chunk-S4CDUXQY.js} +2 -2
- package/dist/{chunk-72OIT7KS.js → chunk-S4Z2OBTX.js} +3 -3
- package/dist/{chunk-4FHRZD5T.js → chunk-SZMYGDSM.js} +2 -2
- package/dist/{chunk-MAH64N55.js → chunk-TBCDF556.js} +4 -4
- package/dist/{chunk-56IV4J5W.js → chunk-TCF4MU7L.js} +443 -58
- package/dist/chunk-TCF4MU7L.js.map +1 -0
- package/dist/{chunk-K66OY4EI.js → chunk-TCQRIIIN.js} +2 -2
- package/dist/{chunk-KXIXO76C.js → chunk-U65VJSCJ.js} +14 -14
- package/dist/{chunk-HNPE66LB.js → chunk-U6NGKS32.js} +7 -7
- package/dist/{chunk-WKJFIMVN.js → chunk-UW4RYPWC.js} +2 -2
- package/dist/{chunk-MN5NOOI7.js → chunk-VG4SSPAW.js} +2 -2
- package/dist/chunk-WFCWP4XU.js +17 -0
- package/dist/chunk-WFCWP4XU.js.map +1 -0
- package/dist/{chunk-UNUMFURP.js → chunk-X5PIDJ3L.js} +3 -3
- package/dist/{chunk-RZ3IZIJG.js → chunk-XOHYGIWF.js} +2 -2
- package/dist/{chunk-MINHJ55X.js → chunk-XXW32OL7.js} +1 -1
- package/dist/{chunk-MINHJ55X.js.map → chunk-XXW32OL7.js.map} +1 -1
- package/dist/{chunk-6RUHELWR.js → chunk-YWPLOJ7T.js} +2 -2
- package/dist/{chunk-ZJPM7GZ3.js → chunk-ZPS724LT.js} +2 -2
- package/dist/{chunk-7UTDHQZ5.js → chunk-ZZZWEDF4.js} +2 -2
- package/dist/{cli-BEkm2MEf.d.ts → cli-CsfFMe6n.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +63 -63
- package/dist/coding/export-okf-codegraph.d.ts +1 -1
- package/dist/coding/export-okf-codegraph.js +9 -9
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +9 -9
- 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 +2 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +9 -9
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +9 -9
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +3 -3
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +11 -11
- 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 +11 -11
- package/dist/cross-lingual-recall.d.ts +1 -1
- 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-BCpeo14F.d.ts → dependency-propagation-delivery-D4WMbOwA.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +9 -9
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/eval-trajectory-contracts.d.ts +1 -1
- package/dist/eval-trajectory-store.d.ts +1 -1
- package/dist/eval-trajectory.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/external-wiki-access.d.ts +11 -11
- package/dist/external-wiki-access.js +23 -23
- 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-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 +9 -9
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/{index-D_pyMUaP.d.ts → index-DuJnzwHv.d.ts} +2 -2
- package/dist/index.d.ts +807 -698
- package/dist/index.js +130 -102
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +10 -10
- 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/location/index.d.ts +3 -3
- package/dist/location/index.js +11 -11
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +9 -9
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +9 -9
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +10 -10
- package/dist/{maintenance-DDUX9d6D.d.ts → maintenance-BBeaeYRR.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-controller.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-subject-cli.d.ts +11 -11
- package/dist/memory-subject.d.ts +11 -11
- 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 +10 -10
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +5 -5
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +9 -9
- 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 +12 -12
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +19 -19
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +18 -18
- package/dist/{orchestrator-3F4jihCo.d.ts → orchestrator-CaqnwNwM.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +86 -84
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CB1dj6Uh.d.ts → pipeline-CrxVjlJr.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{public-http-34-JIAGQ.d.ts → public-http-Cwvl4QZr.d.ts} +1 -1
- package/dist/{qmd-edLLZXc5.d.ts → qmd-BZgbJm0g.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-deep.d.ts +37 -0
- package/dist/recall-deep.js +81 -0
- package/dist/recall-deep.js.map +1 -0
- 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-navigate.d.ts +70 -0
- package/dist/recall-navigate.js +51 -0
- package/dist/recall-navigate.js.map +1 -0
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state-view-wire.d.ts +14 -0
- package/dist/recall-state-view-wire.js +11 -0
- package/dist/recall-state-view-wire.js.map +1 -0
- package/dist/recall-state-view.d.ts +25 -0
- package/dist/recall-state-view.js +22 -0
- package/dist/recall-state-view.js.map +1 -0
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +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 +3 -3
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/schemas.d.ts +152 -152
- package/dist/{scope-profiles-BF2lu81V.d.ts → scope-profiles-DFaojvoP.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 +4 -4
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +10 -10
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-5OuWXBRt.d.ts → semantic-consolidation-BiX68wZA.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +10 -10
- package/dist/semantic-rule-promotion.js +9 -9
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +9 -9
- package/dist/{service-CrqEhLXD.d.ts → service-D5h2zZ0M.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 +7 -7
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +9 -9
- package/dist/{storage-BQn-xnxm.d.ts → storage-CtsaojWD.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +8 -8
- package/dist/subject-config.d.ts +1 -1
- 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 +25 -25
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/export-okf.d.ts +1 -1
- package/dist/transfer/export-okf.js +10 -10
- package/dist/transfer/types.d.ts +78 -78
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-BRpcNjHZ.d.ts → types-CIpfYz1I.d.ts} +16 -11
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +9 -9
- package/dist/who-knows-cli.d.ts +11 -11
- package/dist/who-knows-cli.js +10 -10
- package/dist/who-knows.d.ts +11 -11
- package/dist/who-knows.js +9 -9
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/activity/config.test.ts +1 -1
- package/src/activity/config.ts +48 -3
- package/src/activity/index.ts +2 -0
- package/src/activity/journal.test.ts +97 -0
- package/src/activity/journal.ts +113 -0
- package/src/activity/privacy.test.ts +53 -0
- package/src/activity/privacy.ts +80 -0
- package/src/activity/timeline/index.ts +2 -0
- package/src/activity/timeline/journal-recap.test.ts +113 -0
- package/src/activity/timeline/journal-recap.ts +130 -0
- package/src/activity/timeline/query.test.ts +198 -0
- package/src/activity/timeline/query.ts +313 -0
- package/src/activity/timeline/weekly.test.ts +215 -0
- package/src/activity/timeline/weekly.ts +234 -0
- package/src/activity/types.ts +14 -0
- package/src/activity/vault-publish.test.ts +166 -0
- package/src/activity/vault-publish.ts +101 -0
- package/src/config.test.ts +1 -1
- package/src/config.ts +2 -22
- package/src/dedup/merge-on-write.test.ts +91 -0
- package/src/dedup/merge-on-write.ts +75 -0
- package/src/dedup/novelty-gate.test.ts +143 -0
- package/src/dedup/novelty-gate.ts +163 -0
- package/src/location/recall-exclusion.test.ts +1 -0
- package/src/orchestration/extraction-persist.ts +22 -23
- package/src/orchestration/generic-recall-paths.ts +11 -0
- package/src/orchestration/recall-entry.ts +8 -3
- package/src/recall-deep.test.ts +72 -0
- package/src/recall-deep.ts +113 -0
- package/src/recall-navigate.test.ts +84 -0
- package/src/recall-navigate.ts +100 -0
- package/src/recall-state-view-wire.test.ts +35 -0
- package/src/recall-state-view-wire.ts +28 -0
- package/src/recall-state-view.test.ts +131 -0
- package/src/recall-state-view.ts +138 -0
- package/src/shared-context/governance.test.ts +53 -0
- package/src/shared-context/governance.ts +86 -0
- package/src/types.ts +3 -10
- package/dist/chunk-56IV4J5W.js.map +0 -1
- package/dist/chunk-IHGMRDEE.js.map +0 -1
- package/dist/chunk-KODXCHXJ.js.map +0 -1
- package/dist/chunk-PEBH5DCK.js.map +0 -1
- /package/dist/{chunk-J3OND5QT.js.map → chunk-2FA7U5XY.js.map} +0 -0
- /package/dist/{chunk-GEJKYA7D.js.map → chunk-2ITZ74A6.js.map} +0 -0
- /package/dist/{chunk-2LBAFHOQ.js.map → chunk-2X6BGKQL.js.map} +0 -0
- /package/dist/{chunk-4STAANV7.js.map → chunk-4XLTUR6R.js.map} +0 -0
- /package/dist/{chunk-FTTJRVB7.js.map → chunk-65JOGLIS.js.map} +0 -0
- /package/dist/{chunk-FESUGFIL.js.map → chunk-7UOXCCCI.js.map} +0 -0
- /package/dist/{chunk-6CEGSTBD.js.map → chunk-B4AOWRYF.js.map} +0 -0
- /package/dist/{chunk-FYWLSFFS.js.map → chunk-C5IUOBCN.js.map} +0 -0
- /package/dist/{chunk-FKKGCGYL.js.map → chunk-CHGG74CY.js.map} +0 -0
- /package/dist/{chunk-H7VDIF2V.js.map → chunk-CX4OLNIH.js.map} +0 -0
- /package/dist/{chunk-Z3YEGSR4.js.map → chunk-D3UXGE5D.js.map} +0 -0
- /package/dist/{chunk-7XOG75AU.js.map → chunk-D6Q5EPOV.js.map} +0 -0
- /package/dist/{chunk-MJRGVXPQ.js.map → chunk-EH65UV2Z.js.map} +0 -0
- /package/dist/{chunk-VQ4AMTGZ.js.map → chunk-EWKVYCFP.js.map} +0 -0
- /package/dist/{chunk-23CVL7HS.js.map → chunk-FFUMTH27.js.map} +0 -0
- /package/dist/{chunk-GX6FTSYH.js.map → chunk-GAJK3DQ5.js.map} +0 -0
- /package/dist/{chunk-O57GM3FR.js.map → chunk-GBEOUCBB.js.map} +0 -0
- /package/dist/{chunk-DMEHOEC7.js.map → chunk-H2IRSXZN.js.map} +0 -0
- /package/dist/{chunk-CFVTRUR3.js.map → chunk-H6RSANGQ.js.map} +0 -0
- /package/dist/{chunk-OAJMQKQR.js.map → chunk-IGZCAHFL.js.map} +0 -0
- /package/dist/{chunk-CN4VKV3S.js.map → chunk-INUBU6I5.js.map} +0 -0
- /package/dist/{chunk-CTCGHNWN.js.map → chunk-J2R275FN.js.map} +0 -0
- /package/dist/{chunk-2QSZNTDO.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-VQNRICAQ.js.map → chunk-JKTV3JNX.js.map} +0 -0
- /package/dist/{chunk-33MFRY25.js.map → chunk-KI64TTBL.js.map} +0 -0
- /package/dist/{chunk-VCKWULAK.js.map → chunk-KJXCD7VR.js.map} +0 -0
- /package/dist/{chunk-7LCGFUMB.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-GSKINLAK.js.map → chunk-LJABGXC4.js.map} +0 -0
- /package/dist/{chunk-NPIBN2VL.js.map → chunk-LK4TOYPU.js.map} +0 -0
- /package/dist/{chunk-EZSCW4EM.js.map → chunk-LYUUA6QB.js.map} +0 -0
- /package/dist/{chunk-I5VB44ZK.js.map → chunk-M5ERTI4I.js.map} +0 -0
- /package/dist/{chunk-QCRJMU5V.js.map → chunk-NFP4KPTA.js.map} +0 -0
- /package/dist/{chunk-YXFCALVT.js.map → chunk-NSTNGMSS.js.map} +0 -0
- /package/dist/{chunk-L4X4PJYK.js.map → chunk-NUF7VSEX.js.map} +0 -0
- /package/dist/{chunk-IVIAHQBR.js.map → chunk-OJUEUQDJ.js.map} +0 -0
- /package/dist/{chunk-ZW4VXELZ.js.map → chunk-OMX6TKXH.js.map} +0 -0
- /package/dist/{chunk-EFQCDJZ2.js.map → chunk-QBNE55VA.js.map} +0 -0
- /package/dist/{chunk-6QDXA26G.js.map → chunk-RPIS5FQ7.js.map} +0 -0
- /package/dist/{chunk-HJXA6ZM7.js.map → chunk-S4CDUXQY.js.map} +0 -0
- /package/dist/{chunk-72OIT7KS.js.map → chunk-S4Z2OBTX.js.map} +0 -0
- /package/dist/{chunk-4FHRZD5T.js.map → chunk-SZMYGDSM.js.map} +0 -0
- /package/dist/{chunk-MAH64N55.js.map → chunk-TBCDF556.js.map} +0 -0
- /package/dist/{chunk-K66OY4EI.js.map → chunk-TCQRIIIN.js.map} +0 -0
- /package/dist/{chunk-KXIXO76C.js.map → chunk-U65VJSCJ.js.map} +0 -0
- /package/dist/{chunk-HNPE66LB.js.map → chunk-U6NGKS32.js.map} +0 -0
- /package/dist/{chunk-WKJFIMVN.js.map → chunk-UW4RYPWC.js.map} +0 -0
- /package/dist/{chunk-MN5NOOI7.js.map → chunk-VG4SSPAW.js.map} +0 -0
- /package/dist/{chunk-UNUMFURP.js.map → chunk-X5PIDJ3L.js.map} +0 -0
- /package/dist/{chunk-RZ3IZIJG.js.map → chunk-XOHYGIWF.js.map} +0 -0
- /package/dist/{chunk-6RUHELWR.js.map → chunk-YWPLOJ7T.js.map} +0 -0
- /package/dist/{chunk-ZJPM7GZ3.js.map → chunk-ZPS724LT.js.map} +0 -0
- /package/dist/{chunk-7UTDHQZ5.js.map → chunk-ZZZWEDF4.js.map} +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Isolated merge-on-write judge (issue #2330 first slice).
|
|
3
|
+
*
|
|
4
|
+
* Default off. Persist wiring comes later. Failures create.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_MERGE_MIN = 0.8;
|
|
8
|
+
export const DEFAULT_SKIP_THRESHOLD = 0.92;
|
|
9
|
+
|
|
10
|
+
export const REFUSED_MERGE_CATEGORIES = [
|
|
11
|
+
"procedure",
|
|
12
|
+
"reasoning_trace",
|
|
13
|
+
"moment",
|
|
14
|
+
"correction",
|
|
15
|
+
] as const;
|
|
16
|
+
|
|
17
|
+
export type MergeOnWriteDecision = "merge" | "create";
|
|
18
|
+
export type MergeJudgeVerdict = MergeOnWriteDecision | "uncertain";
|
|
19
|
+
|
|
20
|
+
export interface MergeOnWritePair {
|
|
21
|
+
category: string;
|
|
22
|
+
score: number;
|
|
23
|
+
incomingContent?: string;
|
|
24
|
+
existingContent?: string;
|
|
25
|
+
existingId?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type MergeJudge = (
|
|
29
|
+
pair: MergeOnWritePair,
|
|
30
|
+
) => Promise<MergeJudgeVerdict> | MergeJudgeVerdict;
|
|
31
|
+
|
|
32
|
+
export function shouldConsiderMerge(opts: {
|
|
33
|
+
score: number;
|
|
34
|
+
skipThreshold?: number;
|
|
35
|
+
mergeMin?: number;
|
|
36
|
+
}): boolean {
|
|
37
|
+
const mergeMin = opts.mergeMin ?? DEFAULT_MERGE_MIN;
|
|
38
|
+
const skipThreshold = opts.skipThreshold ?? DEFAULT_SKIP_THRESHOLD;
|
|
39
|
+
if (!(mergeMin > 0)) return false;
|
|
40
|
+
if (!Number.isFinite(opts.score) || !Number.isFinite(skipThreshold)) return false;
|
|
41
|
+
return mergeMin <= opts.score && opts.score < skipThreshold;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function judgeMergeDecision(
|
|
45
|
+
pair: MergeOnWritePair,
|
|
46
|
+
judge: MergeJudge,
|
|
47
|
+
): Promise<MergeOnWriteDecision> {
|
|
48
|
+
try {
|
|
49
|
+
const verdict = await judge(pair);
|
|
50
|
+
return verdict === "merge" ? "merge" : "create";
|
|
51
|
+
} catch {
|
|
52
|
+
return "create";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function applyMergeOnWrite(opts: {
|
|
57
|
+
pair: MergeOnWritePair;
|
|
58
|
+
judge: MergeJudge;
|
|
59
|
+
enabled?: boolean;
|
|
60
|
+
mergeMin?: number;
|
|
61
|
+
skipThreshold?: number;
|
|
62
|
+
}): Promise<MergeOnWriteDecision> {
|
|
63
|
+
if (opts.enabled !== true) return "create";
|
|
64
|
+
if ((REFUSED_MERGE_CATEGORIES as readonly string[]).includes(opts.pair.category)) return "create";
|
|
65
|
+
if (
|
|
66
|
+
!shouldConsiderMerge({
|
|
67
|
+
score: opts.pair.score,
|
|
68
|
+
mergeMin: opts.mergeMin,
|
|
69
|
+
skipThreshold: opts.skipThreshold,
|
|
70
|
+
})
|
|
71
|
+
) {
|
|
72
|
+
return "create";
|
|
73
|
+
}
|
|
74
|
+
return judgeMergeDecision(opts.pair, opts.judge);
|
|
75
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import { parseConfig } from "../config.js";
|
|
5
|
+
import {
|
|
6
|
+
applyNoveltyGate,
|
|
7
|
+
DEFAULT_NOVELTY_ADD_THRESHOLD,
|
|
8
|
+
DEFAULT_NOVELTY_NOOP_THRESHOLD,
|
|
9
|
+
embeddingsFromCosineHits,
|
|
10
|
+
scoreNovelty,
|
|
11
|
+
type NoveltyNeighbor,
|
|
12
|
+
} from "./novelty-gate.js";
|
|
13
|
+
|
|
14
|
+
function neighborAtCosine(id: string, cosine: number): NoveltyNeighbor {
|
|
15
|
+
const s = Math.min(1, Math.max(-1, cosine));
|
|
16
|
+
return { id, embedding: [s, Math.sqrt(Math.max(0, 1 - s * s))] };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const CANDIDATE = [1, 0];
|
|
20
|
+
|
|
21
|
+
test("novelty gate: parseConfig defaults keep the gate off with a wide uncertain band", () => {
|
|
22
|
+
const config = parseConfig({});
|
|
23
|
+
assert.equal(config.noveltyGateEnabled, false);
|
|
24
|
+
assert.equal(config.noveltyAddThreshold, DEFAULT_NOVELTY_ADD_THRESHOLD);
|
|
25
|
+
assert.equal(config.noveltyNoopThreshold, DEFAULT_NOVELTY_NOOP_THRESHOLD);
|
|
26
|
+
assert.ok(config.noveltyAddThreshold - config.noveltyNoopThreshold > 0.3);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("novelty gate: conservative preset stays off", () => {
|
|
30
|
+
const config = parseConfig({ memoryOsPreset: "conservative" });
|
|
31
|
+
assert.equal(config.noveltyGateEnabled, false);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("novelty gate: gate off does not call lookup", async () => {
|
|
35
|
+
let called = 0;
|
|
36
|
+
const decision = await applyNoveltyGate({
|
|
37
|
+
enabled: false,
|
|
38
|
+
addThreshold: DEFAULT_NOVELTY_ADD_THRESHOLD,
|
|
39
|
+
noopThreshold: DEFAULT_NOVELTY_NOOP_THRESHOLD,
|
|
40
|
+
lookup: async () => {
|
|
41
|
+
called += 1;
|
|
42
|
+
throw new Error("lookup must not run when the gate is off");
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
assert.equal(called, 0);
|
|
46
|
+
assert.equal(decision.decision, "uncertain");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("novelty gate: paraphrase routes noop", () => {
|
|
50
|
+
const decision = scoreNovelty(CANDIDATE, [neighborAtCosine("paraphrase", 0.98)]);
|
|
51
|
+
assert.equal(decision.decision, "noop");
|
|
52
|
+
assert.equal(decision.neighborId, "paraphrase");
|
|
53
|
+
assert.ok(decision.score <= DEFAULT_NOVELTY_NOOP_THRESHOLD);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("novelty gate: unrelated routes add", () => {
|
|
57
|
+
const decision = scoreNovelty(CANDIDATE, [neighborAtCosine("other", 0.05)]);
|
|
58
|
+
assert.equal(decision.decision, "add");
|
|
59
|
+
assert.equal(decision.neighborId, "other");
|
|
60
|
+
assert.ok(decision.score >= DEFAULT_NOVELTY_ADD_THRESHOLD);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("novelty gate: exactly at addThreshold is add", () => {
|
|
64
|
+
const neighbor = neighborAtCosine("edge-add", 1 - DEFAULT_NOVELTY_ADD_THRESHOLD);
|
|
65
|
+
const measured = scoreNovelty(CANDIDATE, [neighbor], { addThreshold: 1, noopThreshold: -1 });
|
|
66
|
+
const decision = scoreNovelty(CANDIDATE, [neighbor], {
|
|
67
|
+
addThreshold: measured.score,
|
|
68
|
+
noopThreshold: DEFAULT_NOVELTY_NOOP_THRESHOLD,
|
|
69
|
+
});
|
|
70
|
+
assert.equal(decision.decision, "add");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("novelty gate: exactly at noopThreshold is noop", () => {
|
|
74
|
+
const neighbor = neighborAtCosine("edge-noop", 1 - DEFAULT_NOVELTY_NOOP_THRESHOLD);
|
|
75
|
+
const measured = scoreNovelty(CANDIDATE, [neighbor], { addThreshold: 1, noopThreshold: -1 });
|
|
76
|
+
const decision = scoreNovelty(CANDIDATE, [neighbor], {
|
|
77
|
+
addThreshold: DEFAULT_NOVELTY_ADD_THRESHOLD,
|
|
78
|
+
noopThreshold: measured.score,
|
|
79
|
+
});
|
|
80
|
+
assert.equal(decision.decision, "noop");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("novelty gate: mid-band routes uncertain", () => {
|
|
84
|
+
const mid = (DEFAULT_NOVELTY_ADD_THRESHOLD + DEFAULT_NOVELTY_NOOP_THRESHOLD) / 2;
|
|
85
|
+
const decision = scoreNovelty(CANDIDATE, [neighborAtCosine("mid", 1 - mid)]);
|
|
86
|
+
assert.equal(decision.decision, "uncertain");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("novelty gate: empty neighborhood is add", () => {
|
|
90
|
+
const decision = scoreNovelty(CANDIDATE, []);
|
|
91
|
+
assert.equal(decision.decision, "add");
|
|
92
|
+
assert.equal(decision.score, 1);
|
|
93
|
+
assert.equal(decision.neighborId, undefined);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("novelty gate: thrown lookup is uncertain", async () => {
|
|
97
|
+
const decision = await applyNoveltyGate({
|
|
98
|
+
enabled: true,
|
|
99
|
+
addThreshold: DEFAULT_NOVELTY_ADD_THRESHOLD,
|
|
100
|
+
noopThreshold: DEFAULT_NOVELTY_NOOP_THRESHOLD,
|
|
101
|
+
lookup: async () => {
|
|
102
|
+
throw new Error("backend down");
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
assert.equal(decision.decision, "uncertain");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("novelty gate: cross-connector neighbor cannot noop (PR #2564 review)", () => {
|
|
109
|
+
// Identical content already stored by connector A (cosine ~1) must not
|
|
110
|
+
// suppress connector B's candidate: neighborhood scoped to same-connector
|
|
111
|
+
// neighbors only (mirrors the PR #1852 semantic skip gate).
|
|
112
|
+
const identicalFromA = { id: "a-dup", score: 1, sourceConnector: "connector-a" };
|
|
113
|
+
const { neighborhood } = embeddingsFromCosineHits([identicalFromA], {
|
|
114
|
+
candidateConnector: "connector-b",
|
|
115
|
+
});
|
|
116
|
+
assert.deepEqual(neighborhood, []);
|
|
117
|
+
const decision = scoreNovelty(CANDIDATE, neighborhood);
|
|
118
|
+
assert.equal(decision.decision, "add");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("novelty gate: unattributed neighbor is scoped out when candidate has a connector", () => {
|
|
122
|
+
const unattributed = { id: "anon-dup", score: 1 };
|
|
123
|
+
const { neighborhood } = embeddingsFromCosineHits([unattributed], {
|
|
124
|
+
candidateConnector: "connector-b",
|
|
125
|
+
});
|
|
126
|
+
assert.deepEqual(neighborhood, []);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("novelty gate: same-connector paraphrase still noops", () => {
|
|
130
|
+
const sameConnector = { id: "b-dup", score: 0.98, sourceConnector: "connector-b" };
|
|
131
|
+
const { neighborhood } = embeddingsFromCosineHits([sameConnector], {
|
|
132
|
+
candidateConnector: "connector-b",
|
|
133
|
+
});
|
|
134
|
+
assert.equal(neighborhood.length, 1);
|
|
135
|
+
assert.equal(scoreNovelty(CANDIDATE, neighborhood).decision, "noop");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("novelty gate: candidate without connector keeps unscoped neighborhood", () => {
|
|
139
|
+
const foreign = { id: "a-dup", score: 0.98, sourceConnector: "connector-a" };
|
|
140
|
+
const { neighborhood } = embeddingsFromCosineHits([foreign]);
|
|
141
|
+
assert.equal(neighborhood.length, 1);
|
|
142
|
+
assert.equal(scoreNovelty(CANDIDATE, neighborhood).decision, "noop");
|
|
143
|
+
});
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { coerceBooleanLike, coerceNumber } from "../connectors/coerce.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Embedding-density novelty gate (issue #1953, SAGE).
|
|
5
|
+
*
|
|
6
|
+
* score = 1 - mean(cosine of k nearest). Higher score = more novel.
|
|
7
|
+
* score >= noveltyAddThreshold → add (skip semantic/LLM dedup)
|
|
8
|
+
* score <= noveltyNoopThreshold → noop (drop; do not touch contentHashIndex)
|
|
9
|
+
* else → uncertain (fall through to semantic dedup)
|
|
10
|
+
*
|
|
11
|
+
* Defaults keep a wide UNCERTAIN band. noveltyGateEnabled defaults false.
|
|
12
|
+
* Backend failure is not handled here — callers treat a thrown lookup as uncertain.
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_NOVELTY_ADD_THRESHOLD = 0.55;
|
|
15
|
+
export const DEFAULT_NOVELTY_NOOP_THRESHOLD = 0.15;
|
|
16
|
+
export const DEFAULT_NOVELTY_K = 5;
|
|
17
|
+
|
|
18
|
+
export interface NoveltyNeighbor {
|
|
19
|
+
id: string;
|
|
20
|
+
embedding: number[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface NoveltyDecision {
|
|
24
|
+
score: number;
|
|
25
|
+
decision: "add" | "noop" | "uncertain";
|
|
26
|
+
neighborId?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface NoveltyThresholds {
|
|
30
|
+
addThreshold?: number;
|
|
31
|
+
noopThreshold?: number;
|
|
32
|
+
k?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface WritePathDedupConfig {
|
|
36
|
+
semanticDedupEnabled: boolean;
|
|
37
|
+
semanticDedupThreshold: number;
|
|
38
|
+
semanticDedupCandidates: number;
|
|
39
|
+
noveltyGateEnabled: boolean;
|
|
40
|
+
noveltyAddThreshold: number;
|
|
41
|
+
noveltyNoopThreshold: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function clamp01(value: number | undefined, fallback: number): number {
|
|
45
|
+
return value !== undefined && Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : fallback;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function cosine(a: number[], b: number[]): number {
|
|
49
|
+
if (a.length === 0 || a.length !== b.length) return 0;
|
|
50
|
+
let dot = 0;
|
|
51
|
+
let magA = 0;
|
|
52
|
+
let magB = 0;
|
|
53
|
+
for (let i = 0; i < a.length; i++) {
|
|
54
|
+
dot += a[i] * b[i];
|
|
55
|
+
magA += a[i] * a[i];
|
|
56
|
+
magB += b[i] * b[i];
|
|
57
|
+
}
|
|
58
|
+
const denom = Math.sqrt(magA) * Math.sqrt(magB);
|
|
59
|
+
if (denom === 0) return 0;
|
|
60
|
+
const raw = dot / denom;
|
|
61
|
+
if (!Number.isFinite(raw)) return 0;
|
|
62
|
+
if (raw < 0) return 0;
|
|
63
|
+
if (raw > 1) return 1;
|
|
64
|
+
return raw;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function parseWritePathDedupConfig(cfg: Record<string, unknown>): WritePathDedupConfig {
|
|
68
|
+
const rawCandidates = coerceNumber(cfg.semanticDedupCandidates, "semanticDedupCandidates");
|
|
69
|
+
let semanticDedupCandidates = 5;
|
|
70
|
+
if (rawCandidates !== undefined && rawCandidates >= 0) {
|
|
71
|
+
const n = Math.floor(rawCandidates);
|
|
72
|
+
semanticDedupCandidates = rawCandidates > 0 && n === 0 ? 1 : n;
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
semanticDedupEnabled: coerceBooleanLike(cfg.semanticDedupEnabled, "semanticDedupEnabled") !== false,
|
|
76
|
+
semanticDedupThreshold: clamp01(
|
|
77
|
+
coerceNumber(cfg.semanticDedupThreshold, "semanticDedupThreshold"),
|
|
78
|
+
0.92,
|
|
79
|
+
),
|
|
80
|
+
semanticDedupCandidates,
|
|
81
|
+
noveltyGateEnabled: coerceBooleanLike(cfg.noveltyGateEnabled, "noveltyGateEnabled") === true,
|
|
82
|
+
noveltyAddThreshold: clamp01(
|
|
83
|
+
coerceNumber(cfg.noveltyAddThreshold, "noveltyAddThreshold"),
|
|
84
|
+
DEFAULT_NOVELTY_ADD_THRESHOLD,
|
|
85
|
+
),
|
|
86
|
+
noveltyNoopThreshold: clamp01(
|
|
87
|
+
coerceNumber(cfg.noveltyNoopThreshold, "noveltyNoopThreshold"),
|
|
88
|
+
DEFAULT_NOVELTY_NOOP_THRESHOLD,
|
|
89
|
+
),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function embeddingsFromCosineHits(
|
|
94
|
+
hits: ReadonlyArray<{ id: string; score: number; sourceConnector?: string }>,
|
|
95
|
+
opts: { candidateConnector?: string } = {},
|
|
96
|
+
): { embedding: number[]; neighborhood: NoveltyNeighbor[] } {
|
|
97
|
+
// Connector-aware scoping (PR #2564 review finding on 54d865cb9): a
|
|
98
|
+
// neighbor from a different (or unattributed) connector must not drive a
|
|
99
|
+
// noop — same contract as the semantic skip gate (PR #1852). Candidates
|
|
100
|
+
// without a connector keep the unscoped neighborhood.
|
|
101
|
+
const candidateConnector = opts.candidateConnector?.trim() || undefined;
|
|
102
|
+
const scoped = candidateConnector
|
|
103
|
+
? hits.filter((hit) => (hit.sourceConnector?.trim() || undefined) === candidateConnector)
|
|
104
|
+
: hits;
|
|
105
|
+
return {
|
|
106
|
+
embedding: [1, 0],
|
|
107
|
+
neighborhood: scoped.map((hit) => {
|
|
108
|
+
const s = Number.isFinite(hit.score) ? Math.min(1, Math.max(-1, hit.score)) : 0;
|
|
109
|
+
return { id: hit.id, embedding: [s, Math.sqrt(Math.max(0, 1 - s * s))] };
|
|
110
|
+
}),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function scoreNovelty(
|
|
115
|
+
embedding: number[],
|
|
116
|
+
neighborhood: NoveltyNeighbor[],
|
|
117
|
+
thresholds: NoveltyThresholds = {},
|
|
118
|
+
): NoveltyDecision {
|
|
119
|
+
const addThreshold = clamp01(thresholds.addThreshold ?? DEFAULT_NOVELTY_ADD_THRESHOLD, DEFAULT_NOVELTY_ADD_THRESHOLD);
|
|
120
|
+
const noopThreshold = clamp01(thresholds.noopThreshold ?? DEFAULT_NOVELTY_NOOP_THRESHOLD, DEFAULT_NOVELTY_NOOP_THRESHOLD);
|
|
121
|
+
const k = thresholds.k !== undefined && Number.isFinite(thresholds.k) && thresholds.k > 0
|
|
122
|
+
? Math.floor(thresholds.k)
|
|
123
|
+
: DEFAULT_NOVELTY_K;
|
|
124
|
+
|
|
125
|
+
if (neighborhood.length === 0) {
|
|
126
|
+
return { score: 1, decision: "add" };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const ranked = neighborhood
|
|
130
|
+
.map((neighbor) => ({
|
|
131
|
+
id: neighbor.id,
|
|
132
|
+
cosine: cosine(embedding, neighbor.embedding),
|
|
133
|
+
}))
|
|
134
|
+
.sort((a, b) => b.cosine - a.cosine);
|
|
135
|
+
const nearest = ranked.slice(0, Math.max(1, k));
|
|
136
|
+
const density = nearest.reduce((sum, row) => sum + row.cosine, 0) / nearest.length;
|
|
137
|
+
const score = 1 - density;
|
|
138
|
+
const neighborId = ranked[0]?.id;
|
|
139
|
+
|
|
140
|
+
if (score >= addThreshold) return { score, decision: "add", neighborId };
|
|
141
|
+
if (score <= noopThreshold) return { score, decision: "noop", neighborId };
|
|
142
|
+
return { score, decision: "uncertain", neighborId };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export async function applyNoveltyGate(opts: {
|
|
146
|
+
enabled: boolean;
|
|
147
|
+
addThreshold: number;
|
|
148
|
+
noopThreshold: number;
|
|
149
|
+
lookup: () => Promise<{ embedding: number[]; neighborhood: NoveltyNeighbor[] }>;
|
|
150
|
+
}): Promise<NoveltyDecision> {
|
|
151
|
+
if (!opts.enabled) {
|
|
152
|
+
return { score: 0, decision: "uncertain" };
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const { embedding, neighborhood } = await opts.lookup();
|
|
156
|
+
return scoreNovelty(embedding, neighborhood, {
|
|
157
|
+
addThreshold: opts.addThreshold,
|
|
158
|
+
noopThreshold: opts.noopThreshold,
|
|
159
|
+
});
|
|
160
|
+
} catch {
|
|
161
|
+
return { score: 0, decision: "uncertain" };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -17,6 +17,7 @@ test("isLocationDayPath matches only the top-level day-file shape", () => {
|
|
|
17
17
|
|
|
18
18
|
test("isSearchExcludedPath keeps location day documents out of generic search and recall", () => {
|
|
19
19
|
assert.equal(isSearchExcludedPath("locations/2026-08-17.md"), true);
|
|
20
|
+
assert.equal(isSearchExcludedPath("journal/2026-08-17.md"), true);
|
|
20
21
|
assert.equal(
|
|
21
22
|
isSearchExcludedPath("qmd://collection/locations/2026-08-17.md", {}, "qmd"),
|
|
22
23
|
true,
|
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
} from "../fallback-llm.js";
|
|
84
84
|
import { EmbeddingFallback } from "../embedding-fallback.js";
|
|
85
85
|
import { decideSemanticDedup, type SemanticDedupDecision, type SemanticDedupHit } from "../dedup/semantic.js";
|
|
86
|
+
import { applyNoveltyGate, embeddingsFromCosineHits } from "../dedup/novelty-gate.js";
|
|
86
87
|
import { selectRouteRule, type RouteRule, type RoutingEngineOptions } from "../routing/engine.js";
|
|
87
88
|
import { ThreadingManager } from "../threading.js";
|
|
88
89
|
import { NamespaceStorageRouter } from "../namespaces/storage.js";
|
|
@@ -1919,26 +1920,24 @@ export class ExtractionPersistCoordinator {
|
|
|
1919
1920
|
: undefined;
|
|
1920
1921
|
const faithfulnessEnforceStatus = faithfulnessGateStatus ?? requireSpansPendingStatus ?? injectionScreenStatus;
|
|
1921
1922
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
// a high-similarity update/correction is linked as a superseding
|
|
1939
|
-
// contradiction rather than silently dropped.
|
|
1923
|
+
const novelty = await applyNoveltyGate({
|
|
1924
|
+
enabled: this.deps.config["noveltyGateEnabled"] === true,
|
|
1925
|
+
addThreshold: this.deps.config.noveltyAddThreshold,
|
|
1926
|
+
noopThreshold: this.deps.config.noveltyNoopThreshold,
|
|
1927
|
+
lookup: async () =>
|
|
1928
|
+
embeddingsFromCosineHits(
|
|
1929
|
+
await this.deps.semanticDedupLookup(
|
|
1930
|
+
fact.content,
|
|
1931
|
+
this.deps.config.semanticDedupCandidates,
|
|
1932
|
+
targetStorage,
|
|
1933
|
+
),
|
|
1934
|
+
// Same connector scoping as decideSemanticDedup below: a
|
|
1935
|
+
// cross-connector neighbor must not noop this candidate.
|
|
1936
|
+
{ candidateConnector: sourceContext?.sourceConnector },
|
|
1937
|
+
),
|
|
1938
|
+
});
|
|
1940
1939
|
let pendingSemanticSkip: (SemanticDedupDecision & { action: "skip" }) | null = null;
|
|
1941
|
-
if (resolvePipelineProcessingCapabilities(this.deps.config).semanticDedup && injectionScreenStatus !== "pending_review") {
|
|
1940
|
+
if (novelty.decision !== "add" && resolvePipelineProcessingCapabilities(this.deps.config).semanticDedup && injectionScreenStatus !== "pending_review") {
|
|
1942
1941
|
let semanticDecision: SemanticDedupDecision;
|
|
1943
1942
|
// UUI2: skip embedding lookup for the rest of this batch once we know
|
|
1944
1943
|
// the backend is unavailable. The flag is reset per-batch (set to false
|
|
@@ -2100,17 +2099,17 @@ export class ExtractionPersistCoordinator {
|
|
|
2100
2099
|
// gate's contract is "persists with status: pending_review, never
|
|
2101
2100
|
// silently dropped" (issue #1576).
|
|
2102
2101
|
if (
|
|
2103
|
-
pendingSemanticSkip &&
|
|
2102
|
+
(pendingSemanticSkip || novelty.decision === "noop") &&
|
|
2104
2103
|
!contradictionDetected &&
|
|
2105
2104
|
!isCorrection &&
|
|
2106
2105
|
faithfulnessEnforceStatus !== "pending_review"
|
|
2107
2106
|
) {
|
|
2108
2107
|
log.debug(
|
|
2109
|
-
`dedup: skipping semantic near-duplicate fact "${fact.content
|
|
2108
|
+
`dedup: skipping ${pendingSemanticSkip ? "semantic near-duplicate" : "novelty-noop"} fact "${fact.content
|
|
2110
2109
|
.slice(0, 60)
|
|
2111
|
-
.replace(/\s+/g, " ")}…" score=${pendingSemanticSkip
|
|
2110
|
+
.replace(/\s+/g, " ")}…" score=${(pendingSemanticSkip?.topScore ?? novelty.score).toFixed(
|
|
2112
2111
|
3,
|
|
2113
|
-
)} neighbor=${pendingSemanticSkip.
|
|
2112
|
+
)} neighbor=${pendingSemanticSkip?.topId ?? novelty.neighborId}`,
|
|
2114
2113
|
);
|
|
2115
2114
|
dedupedCount++;
|
|
2116
2115
|
// Do NOT add fact.content to contentHashIndex here. No memory was
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
isLocationDayPath,
|
|
10
10
|
isMeetingRecordPath,
|
|
11
11
|
} from "./orchestrator-helpers.js";
|
|
12
|
+
import { isJournalDayPath } from "../activity/journal.js";
|
|
12
13
|
import { OKF_RESERVED_BASENAMES } from "../okf/type-mapping.js";
|
|
13
14
|
|
|
14
15
|
|
|
@@ -137,6 +138,7 @@ export function isSearchExcludedPath(
|
|
|
137
138
|
isArtifactMemoryPath(candidate) ||
|
|
138
139
|
isNamespacedActivityDigestPath(candidate, policy.memoryDir) ||
|
|
139
140
|
isNamespacedLocationDayPath(candidate, policy.memoryDir) ||
|
|
141
|
+
isNamespacedJournalDayPath(candidate, policy.memoryDir) ||
|
|
140
142
|
isMeetingRecordPath(candidate)
|
|
141
143
|
) {
|
|
142
144
|
return true;
|
|
@@ -179,6 +181,15 @@ function isNamespacedLocationDayPath(candidate: string, memoryDir?: string): boo
|
|
|
179
181
|
return isLocationDayPath(namespaced[2] ?? "", memoryDir);
|
|
180
182
|
}
|
|
181
183
|
|
|
184
|
+
function isNamespacedJournalDayPath(candidate: string, memoryDir?: string): boolean {
|
|
185
|
+
if (isJournalDayPath(candidate, memoryDir)) return true;
|
|
186
|
+
if (memoryDir === undefined || memoryDir.length === 0) return false;
|
|
187
|
+
const relative = path.relative(memoryDir, path.resolve(memoryDir, candidate));
|
|
188
|
+
const namespaced = /^namespaces[\\/]([^\\/]+)[\\/](.*)$/.exec(relative);
|
|
189
|
+
if (namespaced === null) return false;
|
|
190
|
+
return isJournalDayPath(namespaced[2] ?? "", memoryDir);
|
|
191
|
+
}
|
|
192
|
+
|
|
182
193
|
/** A path as given, plus its form with a leading COLLECTION segment removed. */
|
|
183
194
|
function collectionSpellings(
|
|
184
195
|
filePath: string,
|
|
@@ -20,6 +20,7 @@ import { ProfilingCollector } from "../profiling.js";
|
|
|
20
20
|
import { trustResultFor, type TrustStageResultItem } from "../trust-score-stage.js";
|
|
21
21
|
import type { RecallResultFormatter } from "./recall-result-formatter.js";
|
|
22
22
|
import type { IdentityInjectionMode, PluginConfig, QmdSearchResult } from "../types.js";
|
|
23
|
+
import { applyRecallStateViews } from "../recall-state-view-wire.js";
|
|
23
24
|
|
|
24
25
|
export interface RecallEntryDeps {
|
|
25
26
|
appendRecallSection(
|
|
@@ -274,9 +275,13 @@ export class RecallEntryCoordinator {
|
|
|
274
275
|
}): void {
|
|
275
276
|
const sectionId = "memories";
|
|
276
277
|
const trustByPath = options.trustByPath ?? null;
|
|
277
|
-
const injectable =
|
|
278
|
-
|
|
279
|
-
|
|
278
|
+
const injectable = applyRecallStateViews(
|
|
279
|
+
trustByPath
|
|
280
|
+
? options.results.filter((r) => !trustResultFor(trustByPath, r)?.quarantined)
|
|
281
|
+
: options.results,
|
|
282
|
+
options.retrievalQuery,
|
|
283
|
+
this.deps.config,
|
|
284
|
+
);
|
|
280
285
|
if (injectable.length === 0) return;
|
|
281
286
|
|
|
282
287
|
const formatted = this.deps.recallResultFormatter.formatQmdResultEntries(
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
runDeepRecall,
|
|
6
|
+
runDeepRecallStep,
|
|
7
|
+
type DeepRecallState,
|
|
8
|
+
} from "./recall-deep.js";
|
|
9
|
+
|
|
10
|
+
function seed(extra: Partial<DeepRecallState> = {}): DeepRecallState {
|
|
11
|
+
return {
|
|
12
|
+
query: "who met at the cafe",
|
|
13
|
+
workingSet: ["m-seed"],
|
|
14
|
+
frontier: ["m-b", "m-c"],
|
|
15
|
+
budget: 2,
|
|
16
|
+
...extra,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
test("budget 0 stops without calling the policy", () => {
|
|
21
|
+
const result = runDeepRecall(seed({ budget: 0 }), () => {
|
|
22
|
+
throw new Error("policy must not run when budget is 0");
|
|
23
|
+
});
|
|
24
|
+
assert.equal(result.trace.length, 1);
|
|
25
|
+
assert.equal(result.trace[0]?.action, "stop");
|
|
26
|
+
assert.equal(result.state.budget, 0);
|
|
27
|
+
assert.deepEqual(result.state.workingSet, ["m-seed"]);
|
|
28
|
+
assert.deepEqual(result.state.frontier, ["m-b", "m-c"]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("expand consumes budget and pulls the next frontier item", () => {
|
|
32
|
+
const result = runDeepRecallStep(seed({ budget: 2 }), "expand");
|
|
33
|
+
assert.equal(result.step.action, "expand");
|
|
34
|
+
assert.equal(result.state.budget, 1);
|
|
35
|
+
assert.deepEqual(result.state.workingSet, ["m-seed", "m-b"]);
|
|
36
|
+
assert.deepEqual(result.state.frontier, ["m-c"]);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("stop ends while budget remains", () => {
|
|
40
|
+
let calls = 0;
|
|
41
|
+
const result = runDeepRecall(seed({ budget: 4 }), () => {
|
|
42
|
+
calls += 1;
|
|
43
|
+
return "stop";
|
|
44
|
+
});
|
|
45
|
+
assert.equal(calls, 1);
|
|
46
|
+
assert.equal(result.trace.length, 1);
|
|
47
|
+
assert.equal(result.trace[0]?.action, "stop");
|
|
48
|
+
assert.equal(result.state.budget, 4);
|
|
49
|
+
assert.deepEqual(result.state.workingSet, ["m-seed"]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("unknown action throws", () => {
|
|
53
|
+
assert.throws(() => runDeepRecallStep(seed(), "rewrite"), /unknown deep recall action/);
|
|
54
|
+
assert.throws(
|
|
55
|
+
() => runDeepRecall(seed(), () => "rewrite"),
|
|
56
|
+
/unknown deep recall action/,
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("same state and policy produce the same trace", () => {
|
|
61
|
+
const policy = (state: DeepRecallState) => (state.budget > 1 ? "expand" : "refine");
|
|
62
|
+
const start = seed({ budget: 3, frontier: ["m-z", "m-a"] });
|
|
63
|
+
const first = runDeepRecall(start, policy);
|
|
64
|
+
const second = runDeepRecall(start, policy);
|
|
65
|
+
assert.deepEqual(first, second);
|
|
66
|
+
assert.deepEqual(
|
|
67
|
+
first.trace.map((step) => step.action),
|
|
68
|
+
["expand", "expand", "refine", "stop"],
|
|
69
|
+
);
|
|
70
|
+
assert.equal(start.budget, 3);
|
|
71
|
+
assert.deepEqual(start.frontier, ["m-z", "m-a"]);
|
|
72
|
+
});
|