@remnic/core 9.45.5 → 9.46.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 +10 -10
- package/dist/access-admin-ops-surface.js +24 -24
- package/dist/access-authorization-probe.d.ts +10 -10
- package/dist/access-authorization-probe.js +25 -25
- package/dist/access-boundary.d.ts +10 -10
- package/dist/access-boundary.js +24 -24
- package/dist/access-cli.js +73 -71
- 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 +10 -10
- package/dist/access-extraction-force-flush.js +24 -24
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +10 -10
- package/dist/access-http-lifecycle-flush.d.ts +10 -10
- package/dist/access-http-offline-stream.d.ts +10 -10
- package/dist/access-http-query.js +24 -24
- package/dist/access-http.d.ts +10 -10
- package/dist/access-http.js +31 -31
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +24 -24
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +24 -24
- package/dist/access-mcp.d.ts +10 -10
- package/dist/access-mcp.js +28 -28
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-CWUDwB4M.d.ts → access-namespace-preflight--H6HwN85.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +24 -24
- package/dist/access-observe-write-surface.d.ts +10 -10
- package/dist/access-observe-write-surface.js +24 -24
- package/dist/access-offline-manifest.d.ts +8 -8
- package/dist/access-operations-batch.js +25 -25
- package/dist/access-operations.d.ts +10 -10
- package/dist/access-operations.js +27 -27
- package/dist/access-recall-concurrency.d.ts +10 -10
- package/dist/access-recall-concurrency.js +24 -24
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +24 -24
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +24 -24
- package/dist/access-service-helpers.d.ts +10 -10
- package/dist/{access-service-CNN89xyn.d.ts → access-service-loJadYd7.d.ts} +7 -7
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +24 -24
- package/dist/access-surface-catalog.d.ts +10 -10
- 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/ambient-provenance.d.ts +109 -0
- package/dist/ambient-provenance.js +22 -0
- package/dist/ambient-provenance.js.map +1 -0
- package/dist/{auto-sync-UPTUVE4X.js → auto-sync-7O6RP2RT.js} +3 -2
- package/dist/{auto-sync-UPTUVE4X.js.map → auto-sync-7O6RP2RT.js.map} +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +8 -8
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +5 -5
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer-turn-helpers.js +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/buffer.js +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-bctMURhN.d.ts → catalog-Iwbk9h5E.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 +6 -6
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
- package/dist/{chunk-ER7W6H4T.js → chunk-2AD5SXO4.js} +5 -2
- package/dist/chunk-2AD5SXO4.js.map +1 -0
- package/dist/{chunk-CX4ZUMC6.js → chunk-2DSUT7DZ.js} +9 -9
- package/dist/{chunk-DZPFMQZ7.js → chunk-3S63QIFQ.js} +1 -1
- package/dist/chunk-3S63QIFQ.js.map +1 -0
- package/dist/{chunk-DAJPRXBR.js → chunk-47J4EDGR.js} +5 -5
- package/dist/{chunk-QVJPH7SH.js → chunk-5LRDM4R7.js} +40 -40
- package/dist/{chunk-XAGYS7X6.js → chunk-5R6S4DJZ.js} +7 -7
- package/dist/{chunk-QR6G5KF4.js → chunk-5VQPZ4GV.js} +3 -3
- package/dist/{chunk-E5XQIWAL.js → chunk-64BHFFKZ.js} +2 -2
- package/dist/{chunk-GRUYA45P.js → chunk-6H744ZBH.js} +3 -3
- package/dist/{chunk-6ISC4AVB.js → chunk-BDNL34CT.js} +2 -2
- package/dist/{chunk-GQL52GQ5.js → chunk-CDKHKZL5.js} +15 -12
- package/dist/chunk-CDKHKZL5.js.map +1 -0
- package/dist/{chunk-AC5OWJLV.js → chunk-E4FOAENZ.js} +4 -4
- package/dist/{chunk-UW66OZTD.js → chunk-FULKGK7P.js} +2 -2
- package/dist/{chunk-V2TNYF6Q.js → chunk-HJ3SVHUW.js} +3 -3
- package/dist/{chunk-A4IJCD2Z.js → chunk-HXXTXLKA.js} +2 -2
- package/dist/{chunk-FUCYDRE5.js → chunk-IDE5AR5W.js} +11 -11
- package/dist/{chunk-2FSTB6BJ.js → chunk-ILBLZ5Y5.js} +2 -2
- package/dist/chunk-J7T4MX7P.js +131 -0
- package/dist/chunk-J7T4MX7P.js.map +1 -0
- package/dist/{chunk-WZ3TOIDW.js → chunk-JFO5QZ7N.js} +2 -2
- package/dist/{chunk-FR27HBBA.js → chunk-KA47C7BF.js} +2 -2
- package/dist/{chunk-JZH4LWHB.js → chunk-KMWYZTIE.js} +2 -2
- package/dist/{chunk-LPYDOLSM.js → chunk-L7G72WY4.js} +2 -2
- package/dist/{chunk-AMAUBUKY.js → chunk-LI7OE7G6.js} +2 -2
- package/dist/{chunk-MO4HSXHZ.js → chunk-M2INOSTA.js} +2 -2
- package/dist/{chunk-GODSPTOT.js → chunk-M32URQXV.js} +652 -601
- package/dist/chunk-M32URQXV.js.map +1 -0
- package/dist/{chunk-HFPASSFV.js → chunk-P2OTGMTR.js} +2 -2
- package/dist/{chunk-W2V7UESE.js → chunk-PFJXPOD4.js} +2 -2
- package/dist/{chunk-R3KHKU7M.js → chunk-PKCLQ7KM.js} +43 -143
- package/dist/chunk-PKCLQ7KM.js.map +1 -0
- package/dist/chunk-QW27DOHG.js +84 -0
- package/dist/chunk-QW27DOHG.js.map +1 -0
- package/dist/{chunk-QUENPGWZ.js → chunk-RCU25Z66.js} +24 -24
- package/dist/{chunk-QUENPGWZ.js.map → chunk-RCU25Z66.js.map} +1 -1
- package/dist/{chunk-NEF7LR5J.js → chunk-RVPTS4U5.js} +2 -2
- package/dist/{chunk-W3IC7QOY.js → chunk-RVYVMQK4.js} +3 -3
- package/dist/{chunk-GUAL4PQH.js → chunk-ST5IEK3H.js} +2 -2
- package/dist/{chunk-O4KMGRXE.js → chunk-SXWHN7GC.js} +2 -2
- package/dist/{chunk-RNHVVMFN.js → chunk-T6JRMVOV.js} +2 -2
- package/dist/{chunk-5QJQHBLE.js → chunk-U6JGQ37L.js} +2 -2
- package/dist/{chunk-UV72DEZD.js → chunk-UYUYZ4WY.js} +36 -10
- package/dist/chunk-UYUYZ4WY.js.map +1 -0
- package/dist/{chunk-HC3PBX23.js → chunk-V5FE3UAI.js} +2 -2
- package/dist/{chunk-ERZ2R42X.js → chunk-W2ZSNIBP.js} +2 -2
- package/dist/{chunk-3COYXTGM.js → chunk-WHWDBTCJ.js} +2 -2
- package/dist/{chunk-FIK3CQNA.js → chunk-WOC6DXP5.js} +3 -3
- package/dist/{chunk-4FBVAGV3.js → chunk-XBMJ35IP.js} +2 -2
- package/dist/{chunk-GFCVUY6G.js → chunk-YWCOJOUI.js} +2 -2
- package/dist/{chunk-2X2T2UVE.js → chunk-ZDAYWJV6.js} +1 -1
- package/dist/chunk-ZDAYWJV6.js.map +1 -0
- package/dist/{cli-BHBswmUa.d.ts → cli-D_RcqXfZ.d.ts} +5 -5
- package/dist/cli.d.ts +12 -12
- package/dist/cli.js +50 -50
- package/dist/compat/checks.js +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +5 -5
- 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/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +5 -5
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +5 -5
- 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 +7 -7
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +13 -13
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +5 -5
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +8 -8
- package/dist/external-wiki-access.d.ts +10 -10
- package/dist/external-wiki-access.js +25 -25
- 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 +10 -10
- 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-prompt.d.ts +36 -0
- package/dist/extraction-prompt.js +16 -0
- package/dist/extraction-prompt.js.map +1 -0
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +6 -14
- package/dist/extraction.js +9 -7
- 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-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/index.d.ts +23 -20
- package/dist/index.js +124 -122
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- 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 +5 -5
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +5 -5
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +6 -6
- package/dist/{maintenance-CoRikzIt.d.ts → maintenance-DQrL93Uu.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +10 -10
- 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 -12
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +6 -6
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +5 -5
- 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 -14
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +18 -18
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +10 -10
- package/dist/{orchestrator-BJeq7Pw1.d.ts → orchestrator-LPGegii3.d.ts} +8 -8
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +73 -71
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CNjY4wk3.d.ts → pipeline-1h2GpiHP.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/{qmd-C0UDZidt.d.ts → qmd-UdwoF71D.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-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/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-BJzp2F5A.d.ts → scope-profiles-APjhSe-w.d.ts} +1 -1
- package/dist/sdk-compat.js.map +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 -5
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +9 -9
- 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-D4KAZO2G.d.ts → semantic-consolidation-CrySDbk3.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +6 -6
- package/dist/semantic-rule-promotion.js +5 -5
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +5 -5
- package/dist/{service-DWC4tq7p.d.ts → service-DJ0LDyuN.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 +4 -1
- package/dist/source-agent-qualifier.js +6 -6
- package/dist/{storage-DPGjB-8e.d.ts → storage-y340tYKb.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +4 -4
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-yX_FwERf.d.ts → types-D_Au9qJO.d.ts} +13 -2
- 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 +5 -5
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -12
- package/src/ambient-provenance.test.ts +510 -0
- package/src/ambient-provenance.ts +229 -0
- package/src/buffer-turn-helpers.ts +17 -1
- package/src/compat/checks.test.ts +45 -1
- package/src/compat/checks.ts +16 -16
- package/src/extraction-prompt.ts +142 -0
- package/src/extraction.ts +37 -148
- package/src/meetings/memory-gen.test.ts +51 -0
- package/src/meetings/memory-gen.ts +36 -8
- package/src/meetings/summary-extractor.ts +4 -2
- package/src/orchestration/recall-internal.ts +5 -148
- package/src/orchestration/recall-profile-storage.ts +194 -0
- package/src/orchestration/recall-search-pipeline.ts +13 -182
- package/src/orchestration/recall-search-prefilter.ts +254 -0
- package/src/orchestration/session-context.ts +1 -1
- package/src/orchestrator.ts +1 -1
- package/src/sdk-compat.ts +2 -4
- package/src/source-agent-qualifier.ts +3 -0
- package/src/testing/subjects/recall-profile-storage.test.ts +362 -0
- package/src/testing/subjects/recall-search-prefilter.test.ts +365 -0
- package/src/types.ts +2 -2
- package/src/wearables/memory-gen.test.ts +82 -0
- package/src/wearables/memory-gen.ts +54 -5
- package/src/wearables/trust.ts +19 -2
- package/dist/chunk-2X2T2UVE.js.map +0 -1
- package/dist/chunk-DZPFMQZ7.js.map +0 -1
- package/dist/chunk-ER7W6H4T.js.map +0 -1
- package/dist/chunk-GODSPTOT.js.map +0 -1
- package/dist/chunk-GQL52GQ5.js.map +0 -1
- package/dist/chunk-R3KHKU7M.js.map +0 -1
- package/dist/chunk-UV72DEZD.js.map +0 -1
- package/dist/legacy-hook-compat.d.ts +0 -3
- package/dist/legacy-hook-compat.js +0 -36
- package/dist/legacy-hook-compat.js.map +0 -1
- package/src/legacy-hook-compat.test.ts +0 -20
- package/src/legacy-hook-compat.ts +0 -45
- /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-CX4ZUMC6.js.map → chunk-2DSUT7DZ.js.map} +0 -0
- /package/dist/{chunk-DAJPRXBR.js.map → chunk-47J4EDGR.js.map} +0 -0
- /package/dist/{chunk-QVJPH7SH.js.map → chunk-5LRDM4R7.js.map} +0 -0
- /package/dist/{chunk-XAGYS7X6.js.map → chunk-5R6S4DJZ.js.map} +0 -0
- /package/dist/{chunk-QR6G5KF4.js.map → chunk-5VQPZ4GV.js.map} +0 -0
- /package/dist/{chunk-E5XQIWAL.js.map → chunk-64BHFFKZ.js.map} +0 -0
- /package/dist/{chunk-GRUYA45P.js.map → chunk-6H744ZBH.js.map} +0 -0
- /package/dist/{chunk-6ISC4AVB.js.map → chunk-BDNL34CT.js.map} +0 -0
- /package/dist/{chunk-AC5OWJLV.js.map → chunk-E4FOAENZ.js.map} +0 -0
- /package/dist/{chunk-UW66OZTD.js.map → chunk-FULKGK7P.js.map} +0 -0
- /package/dist/{chunk-V2TNYF6Q.js.map → chunk-HJ3SVHUW.js.map} +0 -0
- /package/dist/{chunk-A4IJCD2Z.js.map → chunk-HXXTXLKA.js.map} +0 -0
- /package/dist/{chunk-FUCYDRE5.js.map → chunk-IDE5AR5W.js.map} +0 -0
- /package/dist/{chunk-2FSTB6BJ.js.map → chunk-ILBLZ5Y5.js.map} +0 -0
- /package/dist/{chunk-WZ3TOIDW.js.map → chunk-JFO5QZ7N.js.map} +0 -0
- /package/dist/{chunk-FR27HBBA.js.map → chunk-KA47C7BF.js.map} +0 -0
- /package/dist/{chunk-JZH4LWHB.js.map → chunk-KMWYZTIE.js.map} +0 -0
- /package/dist/{chunk-LPYDOLSM.js.map → chunk-L7G72WY4.js.map} +0 -0
- /package/dist/{chunk-AMAUBUKY.js.map → chunk-LI7OE7G6.js.map} +0 -0
- /package/dist/{chunk-MO4HSXHZ.js.map → chunk-M2INOSTA.js.map} +0 -0
- /package/dist/{chunk-HFPASSFV.js.map → chunk-P2OTGMTR.js.map} +0 -0
- /package/dist/{chunk-W2V7UESE.js.map → chunk-PFJXPOD4.js.map} +0 -0
- /package/dist/{chunk-NEF7LR5J.js.map → chunk-RVPTS4U5.js.map} +0 -0
- /package/dist/{chunk-W3IC7QOY.js.map → chunk-RVYVMQK4.js.map} +0 -0
- /package/dist/{chunk-GUAL4PQH.js.map → chunk-ST5IEK3H.js.map} +0 -0
- /package/dist/{chunk-O4KMGRXE.js.map → chunk-SXWHN7GC.js.map} +0 -0
- /package/dist/{chunk-RNHVVMFN.js.map → chunk-T6JRMVOV.js.map} +0 -0
- /package/dist/{chunk-5QJQHBLE.js.map → chunk-U6JGQ37L.js.map} +0 -0
- /package/dist/{chunk-HC3PBX23.js.map → chunk-V5FE3UAI.js.map} +0 -0
- /package/dist/{chunk-ERZ2R42X.js.map → chunk-W2ZSNIBP.js.map} +0 -0
- /package/dist/{chunk-3COYXTGM.js.map → chunk-WHWDBTCJ.js.map} +0 -0
- /package/dist/{chunk-FIK3CQNA.js.map → chunk-WOC6DXP5.js.map} +0 -0
- /package/dist/{chunk-4FBVAGV3.js.map → chunk-XBMJ35IP.js.map} +0 -0
- /package/dist/{chunk-GFCVUY6G.js.map → chunk-YWCOJOUI.js.map} +0 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { parseConfig } from "../../config.js";
|
|
6
|
+
import type { EmbeddingFallback } from "../../embedding-fallback.js";
|
|
7
|
+
import {
|
|
8
|
+
type PrefilterAndArtifactDeps,
|
|
9
|
+
buildQueryAwarePrefilter,
|
|
10
|
+
fetchActiveArtifactsForNamespace,
|
|
11
|
+
searchEmbeddingFallback,
|
|
12
|
+
searchQueryAwareFallback,
|
|
13
|
+
} from "../../orchestration/recall-search-prefilter.js";
|
|
14
|
+
import type { QueryAwarePrefilter } from "../../orchestrator.js";
|
|
15
|
+
import { StorageManager } from "../../storage.js";
|
|
16
|
+
import type { MemoryFile, PluginConfig, QmdSearchResult } from "../../types.js";
|
|
17
|
+
import { type LifecycleSubject, type MatrixRow, runLifecycleMatrix } from "../lifecycle-matrix.js";
|
|
18
|
+
import { cleanupDir, mkTempMemoryDir } from "../orchestrator-lite.js";
|
|
19
|
+
|
|
20
|
+
interface RecallSearchPrefilterState {
|
|
21
|
+
memoryDir: string;
|
|
22
|
+
config: PluginConfig;
|
|
23
|
+
storage: StorageManager;
|
|
24
|
+
fetchLimitsSeen: number[];
|
|
25
|
+
activeArtifactsResult?: MemoryFile[];
|
|
26
|
+
prefilterResult?: QueryAwarePrefilter;
|
|
27
|
+
prefilterOverflowResult?: QueryAwarePrefilter;
|
|
28
|
+
embeddingResult?: QmdSearchResult[];
|
|
29
|
+
embeddingDisabledResult?: QmdSearchResult[];
|
|
30
|
+
queryAwareFallbackResult?: QmdSearchResult[];
|
|
31
|
+
queryAwareFallbackEmptyResult?: QmdSearchResult[];
|
|
32
|
+
scopedOptionsSeen?: { allowArchived?: boolean };
|
|
33
|
+
scopedNamespacesSeen?: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const subject: LifecycleSubject<RecallSearchPrefilterState> = {
|
|
37
|
+
appliesTo(row: MatrixRow): boolean | string {
|
|
38
|
+
if (row.id === "explicit-provider-identity" || row.id === "restart-reload-recovery") {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return `recall search prefilter helper pipeline has no ${row.id} session/flush/dedupe semantics to realize`;
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
async setup(row: MatrixRow): Promise<RecallSearchPrefilterState> {
|
|
45
|
+
const memoryDir = await mkTempMemoryDir(`recall-search-prefilter-${row.id}`);
|
|
46
|
+
try {
|
|
47
|
+
const config = parseConfig({
|
|
48
|
+
memoryDir,
|
|
49
|
+
queryAwareIndexingEnabled: true,
|
|
50
|
+
queryAwareIndexingMaxCandidates: 100,
|
|
51
|
+
embeddingFallbackEnabled: true,
|
|
52
|
+
});
|
|
53
|
+
const storage = new StorageManager(memoryDir);
|
|
54
|
+
return {
|
|
55
|
+
memoryDir,
|
|
56
|
+
config,
|
|
57
|
+
storage,
|
|
58
|
+
fetchLimitsSeen: [],
|
|
59
|
+
};
|
|
60
|
+
} catch (error) {
|
|
61
|
+
await cleanupDir(memoryDir);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
async exercise(state: RecallSearchPrefilterState, row: MatrixRow): Promise<void> {
|
|
67
|
+
await state.storage.ensureDirectories();
|
|
68
|
+
const stateDir = path.join(state.memoryDir, "state");
|
|
69
|
+
await mkdir(stateDir, { recursive: true });
|
|
70
|
+
|
|
71
|
+
await writeFile(
|
|
72
|
+
path.join(stateDir, "index_tags.json"),
|
|
73
|
+
JSON.stringify({
|
|
74
|
+
version: 2,
|
|
75
|
+
tags: {
|
|
76
|
+
review: { paths: ["facts/a.md", "facts/b.md"] },
|
|
77
|
+
report: { paths: ["facts/b.md", "facts/c.md"] },
|
|
78
|
+
},
|
|
79
|
+
aliases: {},
|
|
80
|
+
}),
|
|
81
|
+
"utf8"
|
|
82
|
+
);
|
|
83
|
+
await writeFile(
|
|
84
|
+
path.join(stateDir, "index_time.json"),
|
|
85
|
+
JSON.stringify({
|
|
86
|
+
version: 2,
|
|
87
|
+
dates: {
|
|
88
|
+
"2026-07-31": ["facts/a.md"],
|
|
89
|
+
},
|
|
90
|
+
events: {},
|
|
91
|
+
}),
|
|
92
|
+
"utf8"
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const writtenMem = await state.storage.writeMemory(
|
|
96
|
+
"fact",
|
|
97
|
+
"Embedding fallback test memory content for hydration verification.",
|
|
98
|
+
{ source: "test-source" }
|
|
99
|
+
);
|
|
100
|
+
const memFile = await state.storage.getMemoryById(writtenMem.id);
|
|
101
|
+
assert.ok(memFile, "stored memory file must exist for embedding test");
|
|
102
|
+
const memPath = memFile.path;
|
|
103
|
+
|
|
104
|
+
if (row.dimensions.restart) {
|
|
105
|
+
state.storage = new StorageManager(state.memoryDir);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const mockArtifacts: MemoryFile[] = [
|
|
109
|
+
{
|
|
110
|
+
path: "artifacts/stale.md",
|
|
111
|
+
content: "stale artifact",
|
|
112
|
+
frontmatter: { sourceMemoryId: "src-stale" },
|
|
113
|
+
} as unknown as MemoryFile,
|
|
114
|
+
{
|
|
115
|
+
path: "artifacts/active1.md",
|
|
116
|
+
content: "active artifact 1",
|
|
117
|
+
frontmatter: { sourceMemoryId: "src-active1" },
|
|
118
|
+
} as unknown as MemoryFile,
|
|
119
|
+
{
|
|
120
|
+
path: "artifacts/active2.md",
|
|
121
|
+
content: "active artifact 2",
|
|
122
|
+
frontmatter: { sourceMemoryId: "src-active2" },
|
|
123
|
+
} as unknown as MemoryFile,
|
|
124
|
+
{
|
|
125
|
+
path: "artifacts/missing.md",
|
|
126
|
+
content: "missing artifact",
|
|
127
|
+
frontmatter: { sourceMemoryId: "src-missing" },
|
|
128
|
+
} as unknown as MemoryFile,
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
const storageRouter = {
|
|
132
|
+
storageFor: async () =>
|
|
133
|
+
({
|
|
134
|
+
searchArtifacts: async (_prompt: string, limit: number) => {
|
|
135
|
+
state.fetchLimitsSeen.push(limit);
|
|
136
|
+
if (state.fetchLimitsSeen.length === 1) {
|
|
137
|
+
return [mockArtifacts[1], ...Array.from({ length: limit - 1 }, () => mockArtifacts[0])];
|
|
138
|
+
}
|
|
139
|
+
return mockArtifacts;
|
|
140
|
+
},
|
|
141
|
+
}) as unknown as StorageManager,
|
|
142
|
+
} as unknown as PrefilterAndArtifactDeps["storageRouter"];
|
|
143
|
+
|
|
144
|
+
const resolveArtifactSourceStatuses = async (
|
|
145
|
+
_stg: unknown,
|
|
146
|
+
sourceIds: string[]
|
|
147
|
+
): Promise<Map<string, "active" | "superseded" | "archived" | "missing">> => {
|
|
148
|
+
const map = new Map<string, "active" | "superseded" | "archived" | "missing">();
|
|
149
|
+
for (const id of sourceIds) {
|
|
150
|
+
if (id === "src-stale") map.set(id, "superseded");
|
|
151
|
+
else if (id === "src-active1" || id === "src-active2") map.set(id, "active");
|
|
152
|
+
else if (id === "src-missing") map.set(id, "missing");
|
|
153
|
+
}
|
|
154
|
+
return map;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
state.activeArtifactsResult = await fetchActiveArtifactsForNamespace(
|
|
158
|
+
{
|
|
159
|
+
storageRouter,
|
|
160
|
+
resolveArtifactSourceStatuses,
|
|
161
|
+
},
|
|
162
|
+
"default",
|
|
163
|
+
"artifact prompt",
|
|
164
|
+
2
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
const scopeQueryAwarePaths = (paths: Set<string> | null, namespaces: string[]): Set<string> | null => {
|
|
168
|
+
state.scopedNamespacesSeen = namespaces;
|
|
169
|
+
return paths;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
state.prefilterResult = await buildQueryAwarePrefilter(
|
|
173
|
+
{
|
|
174
|
+
config: state.config,
|
|
175
|
+
scopeQueryAwarePaths,
|
|
176
|
+
},
|
|
177
|
+
"2026-07-31 #review quarterly report",
|
|
178
|
+
["default"]
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const overflowConfig = parseConfig({
|
|
182
|
+
memoryDir: state.memoryDir,
|
|
183
|
+
queryAwareIndexingEnabled: true,
|
|
184
|
+
queryAwareIndexingMaxCandidates: 1,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
state.prefilterOverflowResult = await buildQueryAwarePrefilter(
|
|
188
|
+
{
|
|
189
|
+
config: overflowConfig,
|
|
190
|
+
scopeQueryAwarePaths,
|
|
191
|
+
},
|
|
192
|
+
"#review quarterly report",
|
|
193
|
+
["default"]
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const embeddingFallback: EmbeddingFallback = {
|
|
197
|
+
isAvailable: async () => true,
|
|
198
|
+
search: async (_query: string, _limit: number) => [
|
|
199
|
+
{
|
|
200
|
+
id: "emb-hit-1",
|
|
201
|
+
path: memPath,
|
|
202
|
+
score: 0.95,
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
} as unknown as EmbeddingFallback;
|
|
206
|
+
|
|
207
|
+
state.embeddingResult = await searchEmbeddingFallback(
|
|
208
|
+
{
|
|
209
|
+
config: state.config,
|
|
210
|
+
embeddingFallback,
|
|
211
|
+
storage: state.storage,
|
|
212
|
+
},
|
|
213
|
+
"hydration query",
|
|
214
|
+
5
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
const disabledConfig = parseConfig({
|
|
218
|
+
memoryDir: state.memoryDir,
|
|
219
|
+
embeddingFallbackEnabled: false,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
state.embeddingDisabledResult = await searchEmbeddingFallback(
|
|
223
|
+
{
|
|
224
|
+
config: disabledConfig,
|
|
225
|
+
embeddingFallback,
|
|
226
|
+
storage: state.storage,
|
|
227
|
+
},
|
|
228
|
+
"hydration query",
|
|
229
|
+
5
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const meetingRecordPath = "meetings/2026-03-10/mtg-2026-03-10-abcdef01.md";
|
|
233
|
+
const recallablePath = "facts/quarterly-report.md";
|
|
234
|
+
|
|
235
|
+
const searchScopedMemoryCandidates = async (
|
|
236
|
+
candidatePaths: Set<string>,
|
|
237
|
+
_query: string,
|
|
238
|
+
limit: number,
|
|
239
|
+
options?: { allowArchived?: boolean }
|
|
240
|
+
): Promise<QmdSearchResult[]> => {
|
|
241
|
+
state.scopedOptionsSeen = options;
|
|
242
|
+
const all: QmdSearchResult[] = [
|
|
243
|
+
{ docid: "doc-mtg", path: meetingRecordPath, score: 0.99, snippet: "meeting" },
|
|
244
|
+
{ docid: "doc-fact", path: recallablePath, score: 0.88, snippet: "fact" },
|
|
245
|
+
];
|
|
246
|
+
return all.filter((item) => candidatePaths.has(item.path)).slice(0, limit);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const prefilterForFallback: QueryAwarePrefilter = {
|
|
250
|
+
candidatePaths: new Set([meetingRecordPath, recallablePath]),
|
|
251
|
+
temporalFromDate: null,
|
|
252
|
+
matchedTags: ["review"],
|
|
253
|
+
expandedTags: ["review"],
|
|
254
|
+
combination: "tag",
|
|
255
|
+
filteredToFullSearch: false,
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
state.queryAwareFallbackResult = await searchQueryAwareFallback(
|
|
259
|
+
{
|
|
260
|
+
config: state.config,
|
|
261
|
+
searchScopedMemoryCandidates,
|
|
262
|
+
},
|
|
263
|
+
"quarterly",
|
|
264
|
+
1,
|
|
265
|
+
prefilterForFallback
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
state.queryAwareFallbackEmptyResult = await searchQueryAwareFallback(
|
|
269
|
+
{
|
|
270
|
+
config: state.config,
|
|
271
|
+
searchScopedMemoryCandidates,
|
|
272
|
+
},
|
|
273
|
+
"quarterly",
|
|
274
|
+
0,
|
|
275
|
+
prefilterForFallback
|
|
276
|
+
);
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
async invariants(state: RecallSearchPrefilterState, _row: MatrixRow): Promise<void> {
|
|
280
|
+
assert.ok(state.activeArtifactsResult, "activeArtifactsResult must be populated");
|
|
281
|
+
assert.equal(state.activeArtifactsResult.length, 2, "must adaptively retrieve targetCount active artifacts");
|
|
282
|
+
assert.deepEqual(
|
|
283
|
+
state.activeArtifactsResult.map((a) => a.path),
|
|
284
|
+
["artifacts/active1.md", "artifacts/active2.md"],
|
|
285
|
+
"must filter out stale and missing source artifacts"
|
|
286
|
+
);
|
|
287
|
+
assert.ok(
|
|
288
|
+
state.fetchLimitsSeen.length > 1,
|
|
289
|
+
"must attempt top-up with grown fetch limit when initial results yield fewer active artifacts than targetCount"
|
|
290
|
+
);
|
|
291
|
+
assert.ok(
|
|
292
|
+
state.fetchLimitsSeen[1] > state.fetchLimitsSeen[0],
|
|
293
|
+
"fetchLimit must adaptively increase across top-up attempts"
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
assert.ok(state.prefilterResult, "prefilterResult must be populated");
|
|
297
|
+
assert.ok(state.prefilterResult.matchedTags.includes("review"), "must extract matched tags from prompt");
|
|
298
|
+
assert.ok(
|
|
299
|
+
state.prefilterResult.candidatePaths instanceof Set,
|
|
300
|
+
"candidatePaths must be a Set when candidate count <= maxCandidates"
|
|
301
|
+
);
|
|
302
|
+
assert.equal(state.prefilterResult.filteredToFullSearch, false, "must not set filteredToFullSearch when under cap");
|
|
303
|
+
assert.equal(
|
|
304
|
+
state.prefilterResult.temporalFromDate,
|
|
305
|
+
"2026-07-31",
|
|
306
|
+
"must combine temporal and tag prefilter inputs"
|
|
307
|
+
);
|
|
308
|
+
assert.deepEqual(
|
|
309
|
+
state.prefilterResult.candidatePaths,
|
|
310
|
+
new Set(["facts/a.md"]),
|
|
311
|
+
"must intersect temporal and tag candidates"
|
|
312
|
+
);
|
|
313
|
+
assert.deepEqual(state.scopedNamespacesSeen, ["default"], "must scope query-aware paths to the recall namespaces");
|
|
314
|
+
|
|
315
|
+
assert.ok(state.prefilterOverflowResult, "prefilterOverflowResult must be populated");
|
|
316
|
+
assert.equal(
|
|
317
|
+
state.prefilterOverflowResult.candidatePaths,
|
|
318
|
+
null,
|
|
319
|
+
"candidatePaths must be reset to null when exceeding maxCandidates"
|
|
320
|
+
);
|
|
321
|
+
assert.equal(
|
|
322
|
+
state.prefilterOverflowResult.filteredToFullSearch,
|
|
323
|
+
true,
|
|
324
|
+
"filteredToFullSearch must be true when candidates exceed maxCandidates"
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
assert.ok(state.embeddingResult, "embeddingResult must be populated");
|
|
328
|
+
assert.equal(state.embeddingResult.length, 1, "must return hydrated search hit");
|
|
329
|
+
assert.equal(state.embeddingResult[0].docid, "emb-hit-1");
|
|
330
|
+
assert.equal(state.embeddingResult[0].score, 0.95);
|
|
331
|
+
assert.match(
|
|
332
|
+
state.embeddingResult[0].snippet,
|
|
333
|
+
/Embedding fallback test memory content for hydration verification/,
|
|
334
|
+
"must hydrate memory content into search snippet"
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
assert.ok(state.embeddingDisabledResult, "embeddingDisabledResult must be populated");
|
|
338
|
+
assert.deepEqual(
|
|
339
|
+
state.embeddingDisabledResult,
|
|
340
|
+
[],
|
|
341
|
+
"must return empty array when embeddingFallback capability is disabled"
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
assert.ok(state.queryAwareFallbackResult, "queryAwareFallbackResult must be populated");
|
|
345
|
+
assert.equal(state.queryAwareFallbackResult.length, 1, "must respect result limit cap");
|
|
346
|
+
assert.equal(
|
|
347
|
+
state.queryAwareFallbackResult[0].path,
|
|
348
|
+
"facts/quarterly-report.md",
|
|
349
|
+
"must exclude meeting record before applying result cap so valid candidate is returned at the cap"
|
|
350
|
+
);
|
|
351
|
+
assert.deepEqual(
|
|
352
|
+
state.scopedOptionsSeen,
|
|
353
|
+
{ allowArchived: true },
|
|
354
|
+
"must request allowArchived when searching candidate paths for historical filtering"
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
assert.deepEqual(state.queryAwareFallbackEmptyResult, [], "must return empty array when limit is zero");
|
|
358
|
+
},
|
|
359
|
+
|
|
360
|
+
async teardown(state: RecallSearchPrefilterState): Promise<void> {
|
|
361
|
+
await cleanupDir(state.memoryDir);
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
runLifecycleMatrix("recall-search-prefilter", subject);
|
package/src/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { ExtractionLivenessConfig } from "./extraction-liveness.js";
|
|
|
6
6
|
import type { ReplicaPeersConfig } from "./replica-peers-config.js";
|
|
7
7
|
import type { ExternalWikiRoot } from "./external-wiki-config.js";
|
|
8
8
|
|
|
9
|
-
import type { BufferTurnOwner } from "./buffer-turn-helpers.js";
|
|
9
|
+
import type { AmbientCaptureProvenance, BufferTurnOwner } from "./buffer-turn-helpers.js";
|
|
10
10
|
export type ReasoningEffort = "none" | "low" | "medium" | "high";
|
|
11
11
|
export type TriggerMode = "smart" | "every_n" | "time_based";
|
|
12
12
|
export type ConvergeConflictPolicy = "newest-wins" | "manual";
|
|
@@ -2643,7 +2643,7 @@ export interface RelevanceFeedback {
|
|
|
2643
2643
|
export interface SourceConnectorProvenance {
|
|
2644
2644
|
sourceConnector?: string;
|
|
2645
2645
|
}
|
|
2646
|
-
export interface BufferTurn extends SourceConnectorProvenance, BufferTurnOwner {
|
|
2646
|
+
export interface BufferTurn extends SourceConnectorProvenance, BufferTurnOwner, AmbientCaptureProvenance {
|
|
2647
2647
|
role: "user" | "assistant";
|
|
2648
2648
|
content: string;
|
|
2649
2649
|
timestamp: string;
|
|
@@ -224,6 +224,33 @@ test("auto mode writes active status", async () => {
|
|
|
224
224
|
assert.equal(writes[0].options.status, "active");
|
|
225
225
|
});
|
|
226
226
|
|
|
227
|
+
test("auto mode still refuses to write a high-impact personal claim active (#2294)", async () => {
|
|
228
|
+
// `auto` has no trust scoring, and an operator may lower minConfidence to or
|
|
229
|
+
// below the speculative ceiling the ambient clamp writes — which would let a
|
|
230
|
+
// clamped TV line straight into recall without this guard.
|
|
231
|
+
const { writer, writes } = makeWriter();
|
|
232
|
+
await generateWearableMemories(
|
|
233
|
+
"limitless",
|
|
234
|
+
"2026-06-10",
|
|
235
|
+
[LONG_CONVERSATION],
|
|
236
|
+
settings({ memoryMode: "auto", minConfidence: 0.3 }),
|
|
237
|
+
REGISTRY,
|
|
238
|
+
{
|
|
239
|
+
extract: extractionReturning([
|
|
240
|
+
{ category: "fact", content: "Dana's mother has a birthday on June 3rd.", confidence: 0.39, tags: [] },
|
|
241
|
+
{ category: "fact", content: "Vendor call happens tomorrow morning.", confidence: 0.8, tags: [] },
|
|
242
|
+
]),
|
|
243
|
+
writer,
|
|
244
|
+
},
|
|
245
|
+
);
|
|
246
|
+
const personal = writes.find((w) => w.content.includes("birthday"));
|
|
247
|
+
assert.ok(personal, "the personal claim was written");
|
|
248
|
+
assert.equal(personal!.options.status, "pending_review");
|
|
249
|
+
const ordinary = writes.find((w) => w.content.includes("Vendor call"));
|
|
250
|
+
assert.ok(ordinary, "the ordinary fact was written");
|
|
251
|
+
assert.equal(ordinary!.options.status, "active");
|
|
252
|
+
});
|
|
253
|
+
|
|
227
254
|
test("gates: confidence floor, importance floor, dedup, and unsupported categories", async () => {
|
|
228
255
|
const { writer, writes } = makeWriter(["Already stored fact about the vendor."]);
|
|
229
256
|
const result = await generateWearableMemories(
|
|
@@ -343,6 +370,61 @@ test("daily digest writes one deterministic episode memory and dedups", async ()
|
|
|
343
370
|
assert.equal(writes2.length, 0);
|
|
344
371
|
});
|
|
345
372
|
|
|
373
|
+
test("review mode queues a clamped personal claim instead of dropping it below the floor (#2294)", async () => {
|
|
374
|
+
// The extraction clamp pins high-impact ambient facts to 0.39, under the 0.6
|
|
375
|
+
// default minConfidence — so without an exemption the pre-filter would drop
|
|
376
|
+
// exactly the candidates review mode promises to queue.
|
|
377
|
+
const { writer, writes } = makeWriter();
|
|
378
|
+
const result = await generateWearableMemories(
|
|
379
|
+
"limitless",
|
|
380
|
+
"2026-06-10",
|
|
381
|
+
[LONG_CONVERSATION],
|
|
382
|
+
settings({ memoryMode: "review" }),
|
|
383
|
+
REGISTRY,
|
|
384
|
+
{
|
|
385
|
+
extract: extractionReturning([
|
|
386
|
+
{ category: "fact", content: "Dana's mother has a birthday on June 3rd.", confidence: 0.39, tags: [] },
|
|
387
|
+
{ category: "fact", content: "A low-signal rumor about the vendor.", confidence: 0.39, tags: [] },
|
|
388
|
+
]),
|
|
389
|
+
writer,
|
|
390
|
+
},
|
|
391
|
+
);
|
|
392
|
+
|
|
393
|
+
assert.equal(writes.length, 1, "only the high-impact claim is exempt from the floor");
|
|
394
|
+
assert.match(writes[0].content, /birthday/);
|
|
395
|
+
assert.equal(writes[0].options.status, "pending_review");
|
|
396
|
+
assert.equal(result.skippedByReason["below-confidence"], 1, "ordinary low-confidence facts still drop");
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
test("a digest whose provider title is a personal claim is held for review (#2294)", async () => {
|
|
400
|
+
// Providers derive conversation.title from the same captured audio, so a
|
|
401
|
+
// title lifted from a television scene must not ride into recall on the
|
|
402
|
+
// digest, which bypasses extraction and its clamp entirely.
|
|
403
|
+
const { writer, writes } = makeWriter();
|
|
404
|
+
const wrote = await writeDailyDigestMemory(
|
|
405
|
+
"limitless",
|
|
406
|
+
"2026-06-10",
|
|
407
|
+
[{ ...LONG_CONVERSATION, title: "Dana's cancer diagnosis" }],
|
|
408
|
+
settings({ memoryMode: "smart" }),
|
|
409
|
+
REGISTRY,
|
|
410
|
+
writer,
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
assert.equal(wrote, true, "the digest is still written, just not active");
|
|
414
|
+
assert.equal(writes[0].options.status, "pending_review");
|
|
415
|
+
|
|
416
|
+
const { writer: clean, writes: cleanWrites } = makeWriter();
|
|
417
|
+
await writeDailyDigestMemory(
|
|
418
|
+
"limitless",
|
|
419
|
+
"2026-06-10",
|
|
420
|
+
[LONG_CONVERSATION],
|
|
421
|
+
settings({ memoryMode: "smart" }),
|
|
422
|
+
REGISTRY,
|
|
423
|
+
clean,
|
|
424
|
+
);
|
|
425
|
+
assert.equal(cleanWrites[0].options.status, "active", "an ordinary digest is unaffected");
|
|
426
|
+
});
|
|
427
|
+
|
|
346
428
|
function judgeReturning(
|
|
347
429
|
kinds: Array<"accept" | "reject" | "defer">,
|
|
348
430
|
): NonNullable<Parameters<typeof generateWearableMemories>[5]["judgeFacts"]> {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
30
|
import { scoreImportance } from "../importance.js";
|
|
31
|
+
import { collectPersonEntityRefs, isHighImpactPersonalFact } from "../ambient-provenance.js";
|
|
31
32
|
import type { MemoryWriteResult } from "../storage.js";
|
|
32
33
|
import {
|
|
33
34
|
composeMemoryEnvelope,
|
|
@@ -241,6 +242,9 @@ export function buildExtractionTurns(
|
|
|
241
242
|
timestamp,
|
|
242
243
|
sourceValidAt: timestamp,
|
|
243
244
|
sessionKey,
|
|
245
|
+
// Always-on capture: this transcript may carry TV, podcast, or
|
|
246
|
+
// overheard speech the wearer never authored (issue #2294).
|
|
247
|
+
ambientCapture: true,
|
|
244
248
|
});
|
|
245
249
|
chunkLines = [];
|
|
246
250
|
chunkChars = 0;
|
|
@@ -258,6 +262,12 @@ interface GatedCandidate {
|
|
|
258
262
|
fact: ExtractedFact;
|
|
259
263
|
importance: ImportanceScore;
|
|
260
264
|
conversation: WearableConversation;
|
|
265
|
+
/**
|
|
266
|
+
* Ambient high-impact verdict, decided where the extraction's entity list is
|
|
267
|
+
* still in scope so personhood comes from the extractor's own `type:
|
|
268
|
+
* "person"` metadata rather than the spelling of `entityRef` (#2294).
|
|
269
|
+
*/
|
|
270
|
+
highImpact: boolean;
|
|
261
271
|
}
|
|
262
272
|
|
|
263
273
|
interface ScoredCandidate {
|
|
@@ -375,6 +385,7 @@ export async function generateWearableMemories(
|
|
|
375
385
|
result.completed = false;
|
|
376
386
|
break;
|
|
377
387
|
}
|
|
388
|
+
const personRefs = collectPersonEntityRefs(extraction);
|
|
378
389
|
for (const fact of extraction.facts) {
|
|
379
390
|
const content = fact.content?.trim();
|
|
380
391
|
if (!content) {
|
|
@@ -385,10 +396,18 @@ export async function generateWearableMemories(
|
|
|
385
396
|
skip("unsupported-category");
|
|
386
397
|
continue;
|
|
387
398
|
}
|
|
399
|
+
const highImpact = isHighImpactPersonalFact({ ...fact, content }, personRefs);
|
|
388
400
|
// In smart mode the trust bands subsume the hard confidence
|
|
389
401
|
// floor — a borderline fact belongs in the review band, not on
|
|
390
402
|
// the floor. The pre-filter applies to review/auto modes only.
|
|
403
|
+
//
|
|
404
|
+
// High-impact ambient claims are exempt: the extraction clamp just
|
|
405
|
+
// pinned them to 0.39, which is below the 0.6 default floor, so the
|
|
406
|
+
// pre-filter would silently drop the very candidates `review` mode
|
|
407
|
+
// promises to queue and would make the auto-mode cap unreachable
|
|
408
|
+
// (#2294). They skip the floor and land pending_review via the cap.
|
|
391
409
|
if (
|
|
410
|
+
highImpact === false &&
|
|
392
411
|
settings.memoryMode !== "smart" &&
|
|
393
412
|
typeof fact.confidence === "number" &&
|
|
394
413
|
fact.confidence < settings.minConfidence
|
|
@@ -410,7 +429,12 @@ export async function generateWearableMemories(
|
|
|
410
429
|
continue;
|
|
411
430
|
}
|
|
412
431
|
seenContent.add(dedupKey);
|
|
413
|
-
candidates.push({
|
|
432
|
+
candidates.push({
|
|
433
|
+
fact: { ...fact, content },
|
|
434
|
+
importance,
|
|
435
|
+
conversation,
|
|
436
|
+
highImpact,
|
|
437
|
+
});
|
|
414
438
|
}
|
|
415
439
|
}
|
|
416
440
|
|
|
@@ -446,8 +470,13 @@ export async function generateWearableMemories(
|
|
|
446
470
|
const promoteScores = await scoreCandidates(promotable, settings, deps, result);
|
|
447
471
|
for (const [index, candidate] of promotable.entries()) {
|
|
448
472
|
const scored = promoteScores.get(index);
|
|
473
|
+
// Every wearable candidate is ambient by construction, so a high-impact
|
|
474
|
+
// personal claim can only ever reach the review queue — late-arriving
|
|
475
|
+
// corroboration must not promote a clamped TV line to active (#2294).
|
|
449
476
|
const decision = scored
|
|
450
|
-
? decideSmart(scored.trust, scored.verdict, settings
|
|
477
|
+
? decideSmart(scored.trust, scored.verdict, settings, {
|
|
478
|
+
capAtReview: candidate.highImpact,
|
|
479
|
+
})
|
|
451
480
|
: undefined;
|
|
452
481
|
if (!scored || !decision) {
|
|
453
482
|
skip("duplicate-existing");
|
|
@@ -536,13 +565,24 @@ export async function generateWearableMemories(
|
|
|
536
565
|
const modeStatus = memoryStatusForMode(settings.memoryMode);
|
|
537
566
|
const writable: Writable[] = [];
|
|
538
567
|
novel.forEach((candidate, index) => {
|
|
568
|
+
// Every wearable candidate is ambient, so a high-impact personal claim can
|
|
569
|
+
// never be written active — on ANY mode. `auto` has no trust scoring and an
|
|
570
|
+
// operator may set minConfidence at or below the speculative ceiling, which
|
|
571
|
+
// would otherwise let a clamped TV line straight into recall (#2294).
|
|
572
|
+
const capAtReview = candidate.highImpact;
|
|
539
573
|
if (settings.memoryMode !== "smart") {
|
|
540
|
-
|
|
574
|
+
const status = capAtReview ? "pending_review" : modeStatus;
|
|
575
|
+
writable.push({
|
|
576
|
+
candidate,
|
|
577
|
+
index,
|
|
578
|
+
status,
|
|
579
|
+
trustAttributes: capAtReview ? { trustDecision: "ambient-high-impact" } : {},
|
|
580
|
+
});
|
|
541
581
|
return;
|
|
542
582
|
}
|
|
543
583
|
const scored = trustById.get(index);
|
|
544
584
|
if (!scored) return;
|
|
545
|
-
const decision = decideSmart(scored.trust, scored.verdict, settings);
|
|
585
|
+
const decision = decideSmart(scored.trust, scored.verdict, settings, { capAtReview });
|
|
546
586
|
if (decision.outcome === "drop") {
|
|
547
587
|
skip(decision.reason);
|
|
548
588
|
return;
|
|
@@ -680,10 +720,19 @@ export async function writeDailyDigestMemory(
|
|
|
680
720
|
},
|
|
681
721
|
{ source: wearableSourceLabel(sourceId) },
|
|
682
722
|
);
|
|
723
|
+
// A provider derives conversation.title from the same captured audio, so a
|
|
724
|
+
// title lifted from a television scene ("Dana's cancer diagnosis") would
|
|
725
|
+
// otherwise ride into recall on the digest, bypassing the extraction prompt
|
|
726
|
+
// and its clamp entirely. Digest content is `moment`, which the classifier
|
|
727
|
+
// already treats as personal-claim-shaped, so this reads the titles alone
|
|
728
|
+
// and holds only a contaminated digest for review (#2294).
|
|
729
|
+
const titleIsHighImpact = lines.some((line) =>
|
|
730
|
+
isHighImpactPersonalFact({ category: "fact", content: line }),
|
|
731
|
+
);
|
|
683
732
|
await writer.writeSealedMemory(digestEnvelope, {
|
|
684
733
|
importance: scoreImportance(content, "moment", ["daily-digest"]),
|
|
685
734
|
contentHashSource: content,
|
|
686
|
-
status: memoryStatusForMode(settings.memoryMode),
|
|
735
|
+
status: titleIsHighImpact ? "pending_review" : memoryStatusForMode(settings.memoryMode),
|
|
687
736
|
memoryKind: "episode",
|
|
688
737
|
});
|
|
689
738
|
return true;
|
package/src/wearables/trust.ts
CHANGED
|
@@ -142,15 +142,30 @@ export interface SmartDecision {
|
|
|
142
142
|
| "judge-deferred"
|
|
143
143
|
| "auto-approved"
|
|
144
144
|
| "queued-for-review"
|
|
145
|
-
| "below-trust"
|
|
145
|
+
| "below-trust"
|
|
146
|
+
| "ambient-high-impact";
|
|
146
147
|
trust: number;
|
|
147
148
|
}
|
|
148
149
|
|
|
150
|
+
export interface SmartDecisionOptions {
|
|
151
|
+
/**
|
|
152
|
+
* Deny auto-approval regardless of score (issue #2294). Set for high-impact
|
|
153
|
+
* personal facts derived from ambient capture: clamping extraction
|
|
154
|
+
* confidence to the speculative ceiling is not enough on its own, because
|
|
155
|
+
* judge-accept plus cross-source and existing-memory boosts sum past
|
|
156
|
+
* `autoApproveTrust` — and two devices in one room recording the same
|
|
157
|
+
* television program corroborate each other perfectly. Such a candidate
|
|
158
|
+
* tops out in the review queue.
|
|
159
|
+
*/
|
|
160
|
+
capAtReview?: boolean;
|
|
161
|
+
}
|
|
162
|
+
|
|
149
163
|
/** Map judge verdict + trust score to the smart-mode decision. */
|
|
150
164
|
export function decideSmart(
|
|
151
165
|
trust: number,
|
|
152
166
|
judgeVerdict: "accept" | "reject" | "defer" | undefined,
|
|
153
167
|
thresholds: { autoApproveTrust: number; reviewTrust: number },
|
|
168
|
+
options?: SmartDecisionOptions,
|
|
154
169
|
): SmartDecision {
|
|
155
170
|
if (judgeVerdict === "reject") {
|
|
156
171
|
return { outcome: "drop", reason: "judge-rejected", trust };
|
|
@@ -159,7 +174,9 @@ export function decideSmart(
|
|
|
159
174
|
return { outcome: "review", reason: "judge-deferred", trust };
|
|
160
175
|
}
|
|
161
176
|
if (trust >= thresholds.autoApproveTrust) {
|
|
162
|
-
return
|
|
177
|
+
return options?.capAtReview === true
|
|
178
|
+
? { outcome: "review", reason: "ambient-high-impact", trust }
|
|
179
|
+
: { outcome: "active", reason: "auto-approved", trust };
|
|
163
180
|
}
|
|
164
181
|
if (trust >= thresholds.reviewTrust) {
|
|
165
182
|
return { outcome: "review", reason: "queued-for-review", trust };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/source-agent-qualifier.ts"],"sourcesContent":["/**\n * Source-agent qualifier helpers for extraction (#2183).\n *\n * Pure leaf module: imports only types and sibling leaf/orchestration helpers,\n * never `extraction.ts`, so it introduces no cycle (extraction-run.ts only\n * type-imports extraction.ts).\n */\nimport { resolvePipelineProcessingCapabilities } from \"./capabilities.js\";\nimport { applyExtractionSourceGrounding } from \"./extraction-source-grounding.js\";\nimport type { ExtractionGroundingRoleSources } from \"./extraction-source-grounding.js\";\nimport { isValidConnectorId } from \"./connectors/index.js\";\nimport { CONNECTOR_LABEL_MAX_LENGTH, knownConnectorIds } from \"./connectors/label.js\";\nimport { deriveSourceConnector } from \"./orchestration/extraction-run.js\";\nimport type { BufferTurn, ExtractionResult, PluginConfig } from \"./types.js\";\n\n\nexport function resolveSourceConnector(turns: readonly BufferTurn[]): string | undefined {\n const contributing = turns.filter((turn) => turn.extractionContextOnly !== true);\n const derived = deriveSourceConnector(contributing);\n if (derived === undefined || !isValidConnectorId(derived)) return undefined;\n return /[\\u0000-\\u001F\\u007F]/.test(derived) ? undefined : derived;\n}\n\n// Same bound as the recall renderer (CONNECTOR_LABEL_MAX_LENGTH) but a DIFFERENT\n// policy: recall TRUNCATES past the bound (a truncated display label cannot\n// mislead), while the prompt SUPPRESSES (a truncated id could collide with a\n// different connector). Do not \"fix\" this inconsistency — it is deliberate.\nexport function headerConnector(connector: string | undefined): string | undefined {\n return connector !== undefined && connector.length <= CONNECTOR_LABEL_MAX_LENGTH ? connector : undefined;\n}\n\nexport function renderExtractionConversation(\n boundedTurns: readonly BufferTurn[],\n sourceConnector: string | undefined,\n): { conversation: string; renderedConversation: string } {\n const renderedConversation = boundedTurns\n .map((t) => `[${t.extractionContextOnly === true ? `context ${t.role}` : t.role}] ${t.content}`)\n .join(\"\\n\\n\");\n const conversation = sourceConnector === undefined\n ? renderedConversation\n : `Source agent: ${sourceConnector}\\n\\nTool and command instructions in this conversation apply to the ${sourceConnector} agent unless they are clearly universal.\\n\\n${renderedConversation}`;\n return { conversation, renderedConversation };\n}\n\nexport interface ExtractionGroundingContext {\n groundingSource: string;\n assertionSource: string;\n roleAssertionSources?: ExtractionGroundingRoleSources;\n messageTimestamp: Date | undefined;\n sourceConnector?: string;\n scopeClassificationEnabled?: boolean;\n}\n\nexport function applyGroundingWithConnector(\n config: PluginConfig,\n result: ExtractionResult,\n ctx: ExtractionGroundingContext,\n): ExtractionResult {\n const caps = resolvePipelineProcessingCapabilities(config);\n const options = { sourceGrounding: caps.sourceGrounding, anchorTemporalExpressions: caps.delinearize };\n const known = buildKnownConnectors(ctx.sourceConnector);\n // Scope-forcing is decoupled from strip/restore (runs without a trusted\n // connector) but gated on the capability: flag off = byte-identical pre-#2183.\n const scoped = ctx.scopeClassificationEnabled === false\n ? result\n : forceProjectScopeOnAnyQualifier(result, known);\n if (ctx.sourceConnector === undefined) {\n return applyExtractionSourceGrounding(scoped, ctx.groundingSource, ctx.assertionSource, ctx.roleAssertionSources, ctx.messageTimestamp, options);\n }\n const prepared = prepareTrustedConnectorQualifier(scoped, ctx.sourceConnector, known);\n const grounded = applyExtractionSourceGrounding(prepared.result, ctx.groundingSource, ctx.assertionSource, ctx.roleAssertionSources, ctx.messageTimestamp, options);\n return restoreTrustedConnectorQualifier(grounded);\n}\n\nfunction buildKnownConnectors(trusted: string | undefined): Set<string> {\n const known = new Set<string>();\n for (const id of knownConnectorIds()) known.add(id.toLowerCase());\n if (trusted !== undefined) known.add(trusted.toLowerCase());\n return known;\n}\n\n/**\n * Parse a leading agent qualifier from fact text. ONE parser, ONE boundary\n * rule, ONE case policy (case-insensitive), ONE definition of \"agent\" (the name\n * must be a known connector ID). Returns the matched agent and the remaining\n * text, or undefined. Both scope-forcing and strip/restore consume this single\n * result so they can never disagree (#2183 round-11).\n */\nfunction parseLeadingQualifier(content: string, known: ReadonlySet<string>): { agent: string; rest: string } | undefined {\n const lower = content.toLowerCase();\n for (const lead of [\"in \", \"for \"]) {\n if (!lower.startsWith(lead)) continue;\n const m = lower.slice(lead.length).match(/^([a-z0-9][a-z0-9._-]*)\\s*,/u);\n if (m && known.has(m[1])) {\n const consumed = lead.length + m[0].length;\n return { agent: m[1], rest: content.slice(consumed).replace(/^[\\s,.;:]+/u, \"\") };\n }\n }\n const pm = lower.match(/^([a-z0-9][a-z0-9._-]*)'s(?![\\p{L}\\p{N}])/u);\n if (pm && known.has(pm[1])) {\n return { agent: pm[1], rest: content.slice(pm[0].length).replace(/^[\\s,.;:]+/u, \"\") };\n }\n return undefined;\n}\n\n/**\n * Force \"project\" scope on any fact whose content starts with a recognised\n * agent qualifier (a known connector name). A qualifier is evidence the fact is\n * agent-tied; which connector it names does not matter.\n */\nfunction forceProjectScopeOnAnyQualifier(result: ExtractionResult, known: ReadonlySet<string>): ExtractionResult {\n let any = false;\n const facts = result.facts.map((fact) => {\n if (fact.scope === \"project\") return fact;\n if (parseLeadingQualifier(fact.content, known) === undefined) return fact;\n any = true;\n return { ...fact, scope: \"project\" as const };\n });\n return any ? { ...result, facts } : result;\n}\n\nconst RESTORE_KEY = \"_qo\";\n\n/**\n * Strip the TRUSTED connector's qualifier for the grounding pass. Uses the same\n * parseLeadingQualifier as scope-forcing, but only strips when the matched agent\n * IS the trusted connector. Each stripped fact carries its original content\n * positionally for collision-free restore.\n */\nfunction prepareTrustedConnectorQualifier(\n result: ExtractionResult,\n trustedConnector: string,\n known: ReadonlySet<string>,\n): { result: ExtractionResult } {\n const trusted = trustedConnector.toLowerCase();\n const facts = result.facts.map((fact) => {\n const parsed = parseLeadingQualifier(fact.content, known);\n if (parsed === undefined || parsed.agent !== trusted) return fact;\n return { ...fact, content: parsed.rest, [RESTORE_KEY]: fact.content };\n }) as ExtractionResult[\"facts\"];\n return { result: { ...result, facts } };\n}\n\nfunction restoreTrustedConnectorQualifier(grounded: ExtractionResult): ExtractionResult {\n let touched = false;\n const facts = grounded.facts.map((fact) => {\n const record = fact as unknown as Record<string, unknown>;\n const original = record[RESTORE_KEY];\n if (typeof original !== \"string\") return fact;\n touched = true;\n const rest = { ...record };\n delete rest[RESTORE_KEY];\n return { ...rest, content: original } as ExtractionResult[\"facts\"][number];\n });\n return touched ? { ...grounded, facts } : grounded;\n}\n"],"mappings":"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","names":[]}
|