@remnic/core 9.64.1 → 9.64.2
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 +12 -11
- package/dist/access-admin-ops-surface.js +23 -22
- package/dist/access-authorization-probe.d.ts +12 -11
- package/dist/access-authorization-probe.js +24 -23
- package/dist/access-boundary.d.ts +13 -12
- package/dist/access-boundary.js +23 -22
- package/dist/access-cli.js +70 -68
- 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 +12 -11
- package/dist/access-extraction-force-flush.js +23 -22
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +12 -11
- package/dist/access-http-lifecycle-flush.d.ts +12 -11
- package/dist/access-http-offline-stream.d.ts +12 -11
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +25 -24
- package/dist/access-http.d.ts +13 -12
- package/dist/access-http.js +40 -39
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +23 -22
- package/dist/access-lcm-surface.d.ts +12 -11
- package/dist/access-lcm-surface.js +23 -22
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +12 -186
- package/dist/access-mcp.js +32 -31
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-Dj9uR4Cq.d.ts → access-namespace-preflight-CYeI1R2_.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +23 -22
- package/dist/access-observe-write-surface.d.ts +12 -11
- package/dist/access-observe-write-surface.js +23 -22
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-operations-batch.js +26 -25
- package/dist/access-operations.d.ts +16 -15
- package/dist/access-operations.js +29 -28
- package/dist/access-recall-concurrency.d.ts +12 -11
- package/dist/access-recall-concurrency.js +23 -22
- package/dist/access-recall-response.d.ts +12 -11
- package/dist/access-recall-response.js +23 -22
- package/dist/access-recall-surface.d.ts +12 -11
- package/dist/access-recall-surface.js +23 -22
- package/dist/access-schema.d.ts +88 -88
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-Bd0lzaHp.d.ts → access-service-BKtdXnyk.d.ts} +358 -76
- package/dist/access-service-helpers.d.ts +12 -11
- package/dist/access-service.d.ts +12 -11
- package/dist/access-service.js +23 -22
- package/dist/access-surface-catalog.d.ts +12 -11
- package/dist/access-surface-catalog.js +27 -24
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/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 +10 -10
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{catalog-rKYbN7zF.d.ts → catalog-CLAqQO2L.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 +11 -11
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-D267K4V5.js → chunk-246HFJVG.js} +2 -2
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-2RZCOG63.js → chunk-2QI2JBLQ.js} +359 -238
- package/dist/chunk-2QI2JBLQ.js.map +1 -0
- package/dist/{chunk-WNO5W2TP.js → chunk-3A46U7XG.js} +2 -2
- package/dist/{chunk-XFAWGUNX.js → chunk-3LOQN3TO.js} +10 -5
- package/dist/chunk-3LOQN3TO.js.map +1 -0
- package/dist/{chunk-5Q5BEWJ3.js → chunk-44DSGZFF.js} +2 -2
- package/dist/{chunk-VENMDW4U.js → chunk-55SJFHVD.js} +6 -6
- package/dist/{chunk-VCBG52MM.js → chunk-5HERQ5FX.js} +7 -7
- package/dist/{chunk-IRXMJLTW.js → chunk-5HK3CJAR.js} +2 -2
- package/dist/{chunk-VSKA2ATE.js → chunk-6LTCUN3T.js} +2 -2
- package/dist/{chunk-IHPYTG6F.js → chunk-7BVO64UC.js} +2 -2
- package/dist/{chunk-ZUIVJ3BB.js → chunk-7V3AZWWZ.js} +4 -4
- package/dist/{chunk-Y5ZIQFWH.js → chunk-A2IBK3TG.js} +2 -2
- package/dist/{chunk-6I6IOMKS.js → chunk-C6AKYOFO.js} +2 -2
- package/dist/{chunk-ZGGTIBWN.js → chunk-CKZHKFY3.js} +3 -3
- package/dist/{chunk-FMGTFMT3.js → chunk-DA2O3F5V.js} +25 -11
- package/dist/chunk-DA2O3F5V.js.map +1 -0
- package/dist/{chunk-GSQDPL45.js → chunk-DC4FJY2G.js} +22 -7
- package/dist/{chunk-GSQDPL45.js.map → chunk-DC4FJY2G.js.map} +1 -1
- package/dist/{chunk-JE3AKPOO.js → chunk-DG6MJD7W.js} +2 -2
- package/dist/{chunk-P4SD7BSA.js → chunk-DHKV6E4A.js} +2 -2
- package/dist/{chunk-KOE3RLNN.js → chunk-EJDLQRUO.js} +2 -2
- package/dist/{chunk-VD2OT77P.js → chunk-GEULB2VI.js} +2 -1
- package/dist/chunk-GEULB2VI.js.map +1 -0
- package/dist/{chunk-DRS3OX77.js → chunk-GVRLED7R.js} +2 -2
- package/dist/{chunk-EAWJSY2Z.js → chunk-H5CGAD7L.js} +1 -1
- package/dist/{chunk-DLZBOEJY.js → chunk-IFK3PVM7.js} +2 -2
- package/dist/{chunk-E7MYSCSL.js → chunk-IJXECCUV.js} +2 -2
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/{chunk-NMQXUGTU.js → chunk-JCSUNXYJ.js} +3 -3
- package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-YY63AMGP.js → chunk-KRPE7ANR.js} +2 -2
- package/dist/{chunk-AGC3Q53R.js → chunk-LOETWOEB.js} +2 -2
- package/dist/{chunk-7X35RPN3.js → chunk-LZKCMK3U.js} +2 -2
- package/dist/{chunk-4KKVDOCD.js → chunk-MJRVF7SF.js} +26 -25
- package/dist/chunk-MJRVF7SF.js.map +1 -0
- package/dist/{chunk-K547KS3X.js → chunk-ML3U4KPR.js} +4 -4
- package/dist/{chunk-HIEWDJ2O.js → chunk-MSTNSVXI.js} +2 -1
- package/dist/chunk-MSTNSVXI.js.map +1 -0
- package/dist/{chunk-CI6YIT5S.js → chunk-NO7B6DRB.js} +2 -2
- package/dist/{chunk-Q3IRE6E4.js → chunk-ON2P3SHG.js} +2 -2
- package/dist/{chunk-2Q4UAPLD.js → chunk-OQIRBGUU.js} +4 -4
- package/dist/{chunk-WDFXRHOZ.js → chunk-PE76XIDM.js} +3 -3
- package/dist/{chunk-MVIYRRVJ.js → chunk-PMVPCZJZ.js} +5 -5
- package/dist/{chunk-VCNGVU62.js → chunk-PVIXAMWM.js} +2 -2
- package/dist/{chunk-QHNO6AND.js → chunk-RWLRKMZK.js} +2 -2
- package/dist/{chunk-UWSETW6O.js → chunk-SB6YBB2V.js} +2 -2
- package/dist/{chunk-DTQ3OB7O.js → chunk-SHQFYZTD.js} +2 -2
- package/dist/chunk-TKI2WOL5.js +256 -0
- package/dist/chunk-TKI2WOL5.js.map +1 -0
- package/dist/chunk-TY35YQ6E.js +77 -0
- package/dist/chunk-TY35YQ6E.js.map +1 -0
- package/dist/{chunk-AL43367I.js → chunk-UMDZXW5J.js} +23 -1
- package/dist/chunk-UMDZXW5J.js.map +1 -0
- package/dist/{chunk-G5OB4XZX.js → chunk-VANZKHTN.js} +4 -4
- package/dist/{chunk-IPUUMLSM.js → chunk-VLES5S4K.js} +271 -62
- package/dist/chunk-VLES5S4K.js.map +1 -0
- package/dist/{chunk-DPPTG6VJ.js → chunk-VRYEXPRX.js} +1 -1
- package/dist/chunk-VRYEXPRX.js.map +1 -0
- package/dist/{chunk-3CYVTO6A.js → chunk-VUP47UJI.js} +3 -3
- package/dist/{chunk-OTVHRZZD.js → chunk-WBM5NR4E.js} +2 -2
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-7D3TTGHY.js → chunk-XACYILRA.js} +38 -12
- package/dist/chunk-XACYILRA.js.map +1 -0
- package/dist/{chunk-B2GICNOJ.js → chunk-XH4IQVTN.js} +2 -2
- package/dist/{chunk-OWAYQK5V.js → chunk-XZUCNVGE.js} +8 -8
- package/dist/{chunk-4FSCGYTQ.js → chunk-YFQTDE7N.js} +2 -2
- package/dist/{chunk-RMB22Q3R.js → chunk-YXGU3MDQ.js} +2 -2
- package/dist/{chunk-XSPRZZEX.js → chunk-Z6CJLYXT.js} +4 -4
- package/dist/{chunk-DZ2AVS2H.js → chunk-ZSYE2QVJ.js} +2 -2
- package/dist/{cli-0dDmOsJ8.d.ts → cli-CLvBewKf.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +56 -55
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +10 -10
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +10 -10
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +10 -10
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +4 -4
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +12 -12
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +12 -12
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-Cr8u-XwC.d.ts → dependency-propagation-delivery-DMqIw9Zh.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 +10 -10
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/external-wiki-access.d.ts +12 -11
- package/dist/external-wiki-access.js +24 -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 +12 -13
- 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 +10 -10
- 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.ts +709 -700
- package/dist/index.js +116 -80
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +11 -11
- 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 +10 -10
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -10
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +11 -11
- package/dist/{maintenance-BpNjuZk4.d.ts → maintenance-DITiehFX.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +12 -11
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-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 +11 -11
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +7 -7
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +10 -10
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +13 -13
- 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 +16 -16
- package/dist/{orchestrator-B3ZQ8CTJ.d.ts → orchestrator-6fPa2l9x.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +70 -68
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-q5emoXD6.d.ts → pipeline-DHpYtfM3.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-CQN-i7Ai.d.ts → public-http-BT36aBb-.d.ts} +1 -1
- package/dist/{qmd-YC6YGphs.d.ts → qmd-BaX31tM0.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/resume-bundles.js +2 -2
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/schemas.d.ts +108 -108
- package/dist/{scope-profiles-De8F7YQ6.d.ts → scope-profiles-1hYWJ9bM.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +6 -6
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +10 -10
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-Bf-hm2LQ.d.ts → semantic-consolidation-Chmddvcg.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +11 -11
- package/dist/semantic-rule-promotion.js +10 -10
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +10 -10
- package/dist/{service-D83osSRn.d.ts → service-DMs_dCCg.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 +9 -9
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +10 -10
- package/dist/{storage-BHWbpbhj.d.ts → storage-CzorrpcN.d.ts} +12 -3
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +9 -9
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +15 -14
- package/dist/support-passport/index.js +26 -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/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/types.d.ts +66 -66
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-CpgsN-Gb.d.ts → types-BP5MC8UU.d.ts} +10 -5
- 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 +10 -10
- package/dist/who-knows-cli.d.ts +155 -0
- package/dist/who-knows-cli.js +109 -0
- package/dist/who-knows-cli.js.map +1 -0
- package/dist/who-knows.d.ts +127 -0
- package/dist/who-knows.js +118 -0
- package/dist/who-knows.js.map +1 -0
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-boundary.ts +1 -0
- package/src/access-http.ts +15 -0
- package/src/access-mcp-output-schemas.ts +1 -0
- package/src/access-mcp.ts +3 -2
- package/src/access-operations-batch.ts +8 -0
- package/src/access-service.ts +26 -0
- package/src/access-surface-catalog.ts +2 -0
- package/src/cli/okf-commands.ts +23 -0
- package/src/cli.ts +2 -1
- package/src/config.ts +2 -1
- package/src/index.ts +3 -0
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/okf/cli.ts +42 -0
- package/src/okf/config.ts +34 -0
- package/src/okf/lint.ts +110 -0
- package/src/okf/sweep.ts +63 -0
- package/src/okf/type-mapping.test.ts +207 -0
- package/src/okf/type-mapping.ts +79 -0
- package/src/orchestrator.ts +2 -0
- package/src/storage/entity-store.ts +9 -5
- package/src/storage/profile-header.ts +33 -9
- package/src/storage/questions-file.ts +50 -0
- package/src/storage.ts +76 -63
- package/src/types.ts +4 -5
- package/src/who-knows-cli.ts +96 -0
- package/src/who-knows.test.ts +257 -0
- package/src/who-knows.ts +364 -0
- package/dist/chunk-2RZCOG63.js.map +0 -1
- package/dist/chunk-4KKVDOCD.js.map +0 -1
- package/dist/chunk-7D3TTGHY.js.map +0 -1
- package/dist/chunk-AL43367I.js.map +0 -1
- package/dist/chunk-DPPTG6VJ.js.map +0 -1
- package/dist/chunk-FMGTFMT3.js.map +0 -1
- package/dist/chunk-HIEWDJ2O.js.map +0 -1
- package/dist/chunk-IPUUMLSM.js.map +0 -1
- package/dist/chunk-VD2OT77P.js.map +0 -1
- package/dist/chunk-XFAWGUNX.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{chunk-D267K4V5.js.map → chunk-246HFJVG.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-WNO5W2TP.js.map → chunk-3A46U7XG.js.map} +0 -0
- /package/dist/{chunk-5Q5BEWJ3.js.map → chunk-44DSGZFF.js.map} +0 -0
- /package/dist/{chunk-VENMDW4U.js.map → chunk-55SJFHVD.js.map} +0 -0
- /package/dist/{chunk-VCBG52MM.js.map → chunk-5HERQ5FX.js.map} +0 -0
- /package/dist/{chunk-IRXMJLTW.js.map → chunk-5HK3CJAR.js.map} +0 -0
- /package/dist/{chunk-VSKA2ATE.js.map → chunk-6LTCUN3T.js.map} +0 -0
- /package/dist/{chunk-IHPYTG6F.js.map → chunk-7BVO64UC.js.map} +0 -0
- /package/dist/{chunk-ZUIVJ3BB.js.map → chunk-7V3AZWWZ.js.map} +0 -0
- /package/dist/{chunk-Y5ZIQFWH.js.map → chunk-A2IBK3TG.js.map} +0 -0
- /package/dist/{chunk-6I6IOMKS.js.map → chunk-C6AKYOFO.js.map} +0 -0
- /package/dist/{chunk-ZGGTIBWN.js.map → chunk-CKZHKFY3.js.map} +0 -0
- /package/dist/{chunk-JE3AKPOO.js.map → chunk-DG6MJD7W.js.map} +0 -0
- /package/dist/{chunk-P4SD7BSA.js.map → chunk-DHKV6E4A.js.map} +0 -0
- /package/dist/{chunk-KOE3RLNN.js.map → chunk-EJDLQRUO.js.map} +0 -0
- /package/dist/{chunk-DRS3OX77.js.map → chunk-GVRLED7R.js.map} +0 -0
- /package/dist/{chunk-EAWJSY2Z.js.map → chunk-H5CGAD7L.js.map} +0 -0
- /package/dist/{chunk-DLZBOEJY.js.map → chunk-IFK3PVM7.js.map} +0 -0
- /package/dist/{chunk-E7MYSCSL.js.map → chunk-IJXECCUV.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-NMQXUGTU.js.map → chunk-JCSUNXYJ.js.map} +0 -0
- /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-YY63AMGP.js.map → chunk-KRPE7ANR.js.map} +0 -0
- /package/dist/{chunk-AGC3Q53R.js.map → chunk-LOETWOEB.js.map} +0 -0
- /package/dist/{chunk-7X35RPN3.js.map → chunk-LZKCMK3U.js.map} +0 -0
- /package/dist/{chunk-K547KS3X.js.map → chunk-ML3U4KPR.js.map} +0 -0
- /package/dist/{chunk-CI6YIT5S.js.map → chunk-NO7B6DRB.js.map} +0 -0
- /package/dist/{chunk-Q3IRE6E4.js.map → chunk-ON2P3SHG.js.map} +0 -0
- /package/dist/{chunk-2Q4UAPLD.js.map → chunk-OQIRBGUU.js.map} +0 -0
- /package/dist/{chunk-WDFXRHOZ.js.map → chunk-PE76XIDM.js.map} +0 -0
- /package/dist/{chunk-MVIYRRVJ.js.map → chunk-PMVPCZJZ.js.map} +0 -0
- /package/dist/{chunk-VCNGVU62.js.map → chunk-PVIXAMWM.js.map} +0 -0
- /package/dist/{chunk-QHNO6AND.js.map → chunk-RWLRKMZK.js.map} +0 -0
- /package/dist/{chunk-UWSETW6O.js.map → chunk-SB6YBB2V.js.map} +0 -0
- /package/dist/{chunk-DTQ3OB7O.js.map → chunk-SHQFYZTD.js.map} +0 -0
- /package/dist/{chunk-G5OB4XZX.js.map → chunk-VANZKHTN.js.map} +0 -0
- /package/dist/{chunk-3CYVTO6A.js.map → chunk-VUP47UJI.js.map} +0 -0
- /package/dist/{chunk-OTVHRZZD.js.map → chunk-WBM5NR4E.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-B2GICNOJ.js.map → chunk-XH4IQVTN.js.map} +0 -0
- /package/dist/{chunk-OWAYQK5V.js.map → chunk-XZUCNVGE.js.map} +0 -0
- /package/dist/{chunk-4FSCGYTQ.js.map → chunk-YFQTDE7N.js.map} +0 -0
- /package/dist/{chunk-RMB22Q3R.js.map → chunk-YXGU3MDQ.js.map} +0 -0
- /package/dist/{chunk-XSPRZZEX.js.map → chunk-Z6CJLYXT.js.map} +0 -0
- /package/dist/{chunk-DZ2AVS2H.js.map → chunk-ZSYE2QVJ.js.map} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
scanMemoryDir
|
|
3
|
+
} from "./chunk-W7IGLX4G.js";
|
|
1
4
|
import {
|
|
2
5
|
isSearchAborted,
|
|
3
6
|
throwIfSearchAborted
|
|
4
7
|
} from "./chunk-GUMZC2BO.js";
|
|
5
|
-
import {
|
|
6
|
-
scanMemoryDir
|
|
7
|
-
} from "./chunk-W7IGLX4G.js";
|
|
8
8
|
import {
|
|
9
9
|
reportSearchDegradation,
|
|
10
10
|
resolveEnsureCollectionArgs
|
|
@@ -776,4 +776,4 @@ export {
|
|
|
776
776
|
resolveOramaCollectionDbFilePath,
|
|
777
777
|
OramaBackend
|
|
778
778
|
};
|
|
779
|
-
//# sourceMappingURL=chunk-
|
|
779
|
+
//# sourceMappingURL=chunk-ML3U4KPR.js.map
|
|
@@ -4,6 +4,7 @@ var MCP_READ_ONLY_TOOL_SUFFIXES = {
|
|
|
4
4
|
recall_explain: true,
|
|
5
5
|
recall_tier_explain: true,
|
|
6
6
|
recall_xray: true,
|
|
7
|
+
who_knows: true,
|
|
7
8
|
briefing: true,
|
|
8
9
|
wearables_status: true,
|
|
9
10
|
transcript_day: true,
|
|
@@ -57,4 +58,4 @@ var MCP_READ_ONLY_TOOL_SUFFIXES = {
|
|
|
57
58
|
export {
|
|
58
59
|
MCP_READ_ONLY_TOOL_SUFFIXES
|
|
59
60
|
};
|
|
60
|
-
//# sourceMappingURL=chunk-
|
|
61
|
+
//# sourceMappingURL=chunk-MSTNSVXI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mcp-read-only-tools.ts"],"sourcesContent":["/**\n * Conservative allowlist of canonical MCP tool suffixes that are\n * unambiguously read-only. Tools in this set are tagged with\n * `annotations: { readOnlyHint: true }` so ChatGPT (and other MCP\n * clients that honor the hint) can skip per-call confirmation.\n *\n * The list is suffix-based so it covers both the `remnic.*` and\n * `engram.*` naming forms. Anything not on it stays unannotated:\n * uncertainty is resolved as \"might mutate\".\n *\n * Excluded by construction: anything that writes, runs a pipeline,\n * flushes, applies, records, imports, or destructively deletes.\n */\nexport const MCP_READ_ONLY_TOOL_SUFFIXES: Readonly<Record<string, true>> = {\n recall: true,\n recall_explain: true,\n recall_tier_explain: true,\n recall_xray: true,\n who_knows: true,\n briefing: true,\n wearables_status: true,\n transcript_day: true,\n transcript_search: true,\n transcript_memories: true,\n meetings_list: true,\n meetings_get: true,\n action_confidence: true,\n capsule_list: true,\n procedural_stats: true,\n memory_get: true,\n memory_timeline: true,\n entity_get: true,\n review_queue_list: true,\n lcm_search: true,\n continuity_incident_list: true,\n identity_anchor_get: true,\n memory_identity: true,\n memory_search: true,\n external_wiki_search: true,\n memory_profile: true,\n memory_entities_list: true,\n memory_questions: true,\n memory_last_recall: true,\n memory_intent_debug: true,\n memory_qmd_debug: true,\n memory_graph_explain: true,\n graph_snapshot: true,\n review_list: true,\n profiling_report: true,\n peer_list: true,\n peer_get: true,\n peer_profile_get: true,\n console_state: true,\n dreams_status: true,\n codegraph_list_projects: true,\n codegraph_index_status: true,\n codegraph_search_graph: true,\n codegraph_trace_path: true,\n codegraph_detect_changes: true,\n codegraph_query_graph: true,\n codegraph_get_schema: true,\n codegraph_get_snippet: true,\n codegraph_get_architecture: true,\n codegraph_search_code: true,\n support_passport_memory_preview: true,\n support_passport_cards_list: true,\n support_passport_grants_list: true,\n};\n"],"mappings":";AAaO,IAAM,8BAA8D;AAAA,EACzE,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,iCAAiC;AAAA,EACjC,6BAA6B;AAAA,EAC7B,8BAA8B;AAChC;","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-B7RWBZXW.js";
|
|
4
4
|
import {
|
|
5
5
|
StorageManager
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2QI2JBLQ.js";
|
|
7
7
|
import {
|
|
8
8
|
getCachedEpisodeMap,
|
|
9
9
|
setCachedEpisodeMap
|
|
@@ -109,4 +109,4 @@ export {
|
|
|
109
109
|
compareVerifiedEpisodeResults,
|
|
110
110
|
searchVerifiedEpisodes
|
|
111
111
|
};
|
|
112
|
-
//# sourceMappingURL=chunk-
|
|
112
|
+
//# sourceMappingURL=chunk-NO7B6DRB.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveDefaultNamespaceRoot,
|
|
3
3
|
resolveNamespaceStorageRoot
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GVRLED7R.js";
|
|
5
5
|
import {
|
|
6
6
|
MutationSerializer,
|
|
7
7
|
withHeldFileLock
|
|
@@ -1473,4 +1473,4 @@ export {
|
|
|
1473
1473
|
isNamespaceKind,
|
|
1474
1474
|
NamespaceCatalog
|
|
1475
1475
|
};
|
|
1476
|
-
//# sourceMappingURL=chunk-
|
|
1476
|
+
//# sourceMappingURL=chunk-ON2P3SHG.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
scanMemoryDir
|
|
3
|
+
} from "./chunk-W7IGLX4G.js";
|
|
1
4
|
import {
|
|
2
5
|
isSearchAborted,
|
|
3
6
|
throwIfSearchAborted
|
|
4
7
|
} from "./chunk-GUMZC2BO.js";
|
|
5
|
-
import {
|
|
6
|
-
scanMemoryDir
|
|
7
|
-
} from "./chunk-W7IGLX4G.js";
|
|
8
8
|
import {
|
|
9
9
|
reportSearchDegradation,
|
|
10
10
|
resolveEnsureCollectionArgs
|
|
@@ -508,4 +508,4 @@ function isMissingVectorProviderColumnError(err) {
|
|
|
508
508
|
export {
|
|
509
509
|
LanceDbBackend
|
|
510
510
|
};
|
|
511
|
-
//# sourceMappingURL=chunk-
|
|
511
|
+
//# sourceMappingURL=chunk-OQIRBGUU.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hasMemoryData
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ON2P3SHG.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveNamespaceStorageRoot
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GVRLED7R.js";
|
|
7
7
|
import {
|
|
8
8
|
getConfiguredNamespaces
|
|
9
9
|
} from "./chunk-Q57GOHLF.js";
|
|
@@ -724,4 +724,4 @@ export {
|
|
|
724
724
|
runNamespaceMaintenancePlan,
|
|
725
725
|
runNamespaceMaintenanceBatchPlan
|
|
726
726
|
};
|
|
727
|
-
//# sourceMappingURL=chunk-
|
|
727
|
+
//# sourceMappingURL=chunk-PE76XIDM.js.map
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
requestEntityCanonicalIdReconcile,
|
|
14
14
|
withRawEntityPageMutation
|
|
15
15
|
} from "./chunk-ZVPVTPGI.js";
|
|
16
|
-
import {
|
|
17
|
-
decryptCapsuleFileInMemory,
|
|
18
|
-
isEncryptedCapsuleFile
|
|
19
|
-
} from "./chunk-UVYI6VIX.js";
|
|
20
16
|
import {
|
|
21
17
|
parseExportBundle
|
|
22
18
|
} from "./chunk-WEHSQBFR.js";
|
|
19
|
+
import {
|
|
20
|
+
decryptCapsuleFileInMemory,
|
|
21
|
+
isEncryptedCapsuleFile
|
|
22
|
+
} from "./chunk-X7Y7WX73.js";
|
|
23
23
|
import {
|
|
24
24
|
assertIsDirectoryNotSymlink,
|
|
25
25
|
assertRealpathInsideRoot,
|
|
@@ -294,4 +294,4 @@ function mintForkId(capsuleId, originalId, now) {
|
|
|
294
294
|
export {
|
|
295
295
|
importCapsule
|
|
296
296
|
};
|
|
297
|
-
//# sourceMappingURL=chunk-
|
|
297
|
+
//# sourceMappingURL=chunk-PMVPCZJZ.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-UYCIS6V5.js";
|
|
8
8
|
import {
|
|
9
9
|
StorageManager
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2QI2JBLQ.js";
|
|
11
11
|
import {
|
|
12
12
|
parseContinuityImprovementLoops
|
|
13
13
|
} from "./chunk-LDXUBPMO.js";
|
|
@@ -1283,4 +1283,4 @@ export {
|
|
|
1283
1283
|
defaultTierMigrationCycleBudget,
|
|
1284
1284
|
CompoundingEngine
|
|
1285
1285
|
};
|
|
1286
|
-
//# sourceMappingURL=chunk-
|
|
1286
|
+
//# sourceMappingURL=chunk-PVIXAMWM.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
computeCorpusWatermarks,
|
|
6
6
|
resolveCorpusNamespaceRoots
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SB6YBB2V.js";
|
|
8
8
|
|
|
9
9
|
// src/operator-doctor-corpus.ts
|
|
10
10
|
var DIGEST_PREFIX_LENGTH = 12;
|
|
@@ -78,4 +78,4 @@ export {
|
|
|
78
78
|
corpusWatermarksFromCheck,
|
|
79
79
|
summarizeCorpusAndReplica
|
|
80
80
|
};
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
81
|
+
//# sourceMappingURL=chunk-RWLRKMZK.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
listNamespaces
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CKZHKFY3.js";
|
|
4
4
|
import {
|
|
5
5
|
capabilityAllowsNamespace
|
|
6
6
|
} from "./chunk-MZWSOLMT.js";
|
|
@@ -282,4 +282,4 @@ export {
|
|
|
282
282
|
computeServiceCorpusWatermarks,
|
|
283
283
|
computeServiceCorpusCensus
|
|
284
284
|
};
|
|
285
|
-
//# sourceMappingURL=chunk-
|
|
285
|
+
//# sourceMappingURL=chunk-SB6YBB2V.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-SOBJ6NEY.js";
|
|
4
4
|
import {
|
|
5
5
|
summarizeDisclosureTokens
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IFK3PVM7.js";
|
|
7
7
|
import {
|
|
8
8
|
summarizeRetrievedMemoryProvenance
|
|
9
9
|
} from "./chunk-I4WBNM3M.js";
|
|
@@ -606,4 +606,4 @@ export {
|
|
|
606
606
|
renderRecallExplain,
|
|
607
607
|
parseRecallExplainFormat
|
|
608
608
|
};
|
|
609
|
-
//# sourceMappingURL=chunk-
|
|
609
|
+
//# sourceMappingURL=chunk-SHQFYZTD.js.map
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseEntityFile
|
|
3
|
+
} from "./chunk-2QI2JBLQ.js";
|
|
4
|
+
import {
|
|
5
|
+
inferMemoryStatus
|
|
6
|
+
} from "./chunk-7RJUVTVF.js";
|
|
7
|
+
import {
|
|
8
|
+
EngramAccessInputError
|
|
9
|
+
} from "./chunk-2Z24E5W2.js";
|
|
10
|
+
|
|
11
|
+
// src/who-knows.ts
|
|
12
|
+
var WHO_KNOWS_DEFAULT_LIMIT = 5;
|
|
13
|
+
var WHO_KNOWS_MAX_LIMIT = 50;
|
|
14
|
+
var WHO_KNOWS_MAX_EVIDENCE = 50;
|
|
15
|
+
var WHO_KNOWS_AUTHORSHIP_BONUS = 1.5;
|
|
16
|
+
async function loadWhoKnowsEntities(storage, entitySchemas) {
|
|
17
|
+
const entities = [];
|
|
18
|
+
for (const id of await storage.listEntityNames()) {
|
|
19
|
+
const raw = await storage.readEntity(id);
|
|
20
|
+
if (!raw) continue;
|
|
21
|
+
try {
|
|
22
|
+
const entity = parseEntityFile(raw, entitySchemas);
|
|
23
|
+
entities.push({ id, name: entity.name, aliases: entity.aliases });
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return entities;
|
|
28
|
+
}
|
|
29
|
+
function validateWhoKnowsInput(topic, limit) {
|
|
30
|
+
if (topic.trim().length === 0) {
|
|
31
|
+
throw new EngramAccessInputError("whoKnows: topic is required and must be non-empty");
|
|
32
|
+
}
|
|
33
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > WHO_KNOWS_MAX_LIMIT) {
|
|
34
|
+
throw new EngramAccessInputError(
|
|
35
|
+
`whoKnows: limit expects an integer between 1 and ${WHO_KNOWS_MAX_LIMIT}`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
var STOPWORDS = {
|
|
40
|
+
the: true,
|
|
41
|
+
a: true,
|
|
42
|
+
an: true,
|
|
43
|
+
of: true,
|
|
44
|
+
and: true,
|
|
45
|
+
or: true,
|
|
46
|
+
to: true,
|
|
47
|
+
in: true,
|
|
48
|
+
for: true,
|
|
49
|
+
on: true,
|
|
50
|
+
with: true,
|
|
51
|
+
is: true,
|
|
52
|
+
are: true,
|
|
53
|
+
was: true,
|
|
54
|
+
were: true,
|
|
55
|
+
who: true,
|
|
56
|
+
knows: true,
|
|
57
|
+
know: true,
|
|
58
|
+
about: true,
|
|
59
|
+
at: true,
|
|
60
|
+
by: true
|
|
61
|
+
};
|
|
62
|
+
function tokenizeTopic(topic) {
|
|
63
|
+
const tokens = topic.toLowerCase().split(/[^a-z0-9]+/).filter((token) => token.length >= 2 && STOPWORDS[token] !== true);
|
|
64
|
+
return [...new Set(tokens)];
|
|
65
|
+
}
|
|
66
|
+
var ATTRIBUTION_VERBS = "said|says|mentioned|noted|explained|recommended|suggested|proposed|wrote|asked|answered|demonstrated|designed|built|debugged|fixed";
|
|
67
|
+
function escapeRegex(text) {
|
|
68
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
69
|
+
}
|
|
70
|
+
function wordMatcher(term) {
|
|
71
|
+
return new RegExp(`\\b${escapeRegex(term.toLowerCase())}\\b`);
|
|
72
|
+
}
|
|
73
|
+
function computeWhoKnows(input) {
|
|
74
|
+
const topicTokens = tokenizeTopic(input.topic);
|
|
75
|
+
const byId = new Map(input.entities.map((entity) => [entity.id, entity]));
|
|
76
|
+
const mentionMatchers = [];
|
|
77
|
+
const authorshipMatchers = [];
|
|
78
|
+
for (const entity of input.entities) {
|
|
79
|
+
for (const term of [entity.name, ...entity.aliases]) {
|
|
80
|
+
const clean = term.trim().toLowerCase();
|
|
81
|
+
if (clean.length < 2) continue;
|
|
82
|
+
mentionMatchers.push({ entityId: entity.id, matcher: wordMatcher(clean) });
|
|
83
|
+
const possessive = clean.replace(/'/g, "");
|
|
84
|
+
authorshipMatchers.push({
|
|
85
|
+
entityId: entity.id,
|
|
86
|
+
matcher: new RegExp(
|
|
87
|
+
`\\b${escapeRegex(possessive)}(?:'s)?\\b[^.!?]{0,40}\\b(?:${ATTRIBUTION_VERBS})\\b`
|
|
88
|
+
)
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
93
|
+
const credit = (entityId, memory, weight, authorship) => {
|
|
94
|
+
let candidate = candidates.get(entityId);
|
|
95
|
+
if (!candidate) {
|
|
96
|
+
candidate = {
|
|
97
|
+
entityId,
|
|
98
|
+
entityName: byId.get(entityId)?.name ?? null,
|
|
99
|
+
rawScore: 0,
|
|
100
|
+
evidence: [],
|
|
101
|
+
matchCount: 0,
|
|
102
|
+
authorshipCount: 0,
|
|
103
|
+
lastSeen: null
|
|
104
|
+
};
|
|
105
|
+
candidates.set(entityId, candidate);
|
|
106
|
+
}
|
|
107
|
+
candidate.rawScore += weight;
|
|
108
|
+
candidate.matchCount += 1;
|
|
109
|
+
candidate.authorshipCount += authorship ? 1 : 0;
|
|
110
|
+
const updated = memory.frontmatter.updated || memory.frontmatter.created;
|
|
111
|
+
if (updated && (!candidate.lastSeen || updated > candidate.lastSeen)) {
|
|
112
|
+
candidate.lastSeen = updated;
|
|
113
|
+
}
|
|
114
|
+
if (candidate.evidence.length < WHO_KNOWS_MAX_EVIDENCE) {
|
|
115
|
+
candidate.evidence.push({
|
|
116
|
+
id: memory.frontmatter.id,
|
|
117
|
+
path: memory.path,
|
|
118
|
+
updated: memory.frontmatter.updated || memory.frontmatter.created
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
for (const memory of input.memories) {
|
|
123
|
+
if (inferMemoryStatus(memory.frontmatter, memory.path) !== "active") continue;
|
|
124
|
+
const haystack = `${memory.content}
|
|
125
|
+
${memory.frontmatter.tags.join(" ")}`.toLowerCase();
|
|
126
|
+
const matched = topicTokens.filter((token) => haystack.includes(token));
|
|
127
|
+
if (matched.length === 0) continue;
|
|
128
|
+
const coverage = matched.length / topicTokens.length;
|
|
129
|
+
const importance = memory.frontmatter.importance?.score ?? 0.5;
|
|
130
|
+
const confidence = memory.frontmatter.confidence ?? 0.5;
|
|
131
|
+
let weight = coverage * (0.5 + 0.5 * importance) * confidence;
|
|
132
|
+
const attributed = /* @__PURE__ */ new Set();
|
|
133
|
+
if (memory.frontmatter.entityRef) attributed.add(memory.frontmatter.entityRef);
|
|
134
|
+
for (const { entityId, matcher } of mentionMatchers) {
|
|
135
|
+
if (matcher.test(haystack)) attributed.add(entityId);
|
|
136
|
+
}
|
|
137
|
+
if (attributed.size === 0) continue;
|
|
138
|
+
const attributedAuthors = /* @__PURE__ */ new Set();
|
|
139
|
+
for (const { entityId, matcher } of authorshipMatchers) {
|
|
140
|
+
if (attributed.has(entityId) && matcher.test(haystack)) attributedAuthors.add(entityId);
|
|
141
|
+
}
|
|
142
|
+
for (const entityId of attributed) {
|
|
143
|
+
const authorship = attributedAuthors.has(entityId);
|
|
144
|
+
credit(entityId, memory, authorship ? weight * WHO_KNOWS_AUTHORSHIP_BONUS : weight, authorship);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const ranked = [...candidates.values()].sort((a, b) => {
|
|
148
|
+
if (b.rawScore !== a.rawScore) return b.rawScore - a.rawScore;
|
|
149
|
+
const aSeen = a.lastSeen ?? "";
|
|
150
|
+
const bSeen = b.lastSeen ?? "";
|
|
151
|
+
if (aSeen !== bSeen) return aSeen < bSeen ? 1 : -1;
|
|
152
|
+
return a.entityId < b.entityId ? -1 : a.entityId > b.entityId ? 1 : 0;
|
|
153
|
+
});
|
|
154
|
+
const top = ranked.slice(0, input.limit);
|
|
155
|
+
const maxScore = top.length > 0 ? top[0].rawScore : 0;
|
|
156
|
+
const results = top.map((candidate) => ({
|
|
157
|
+
entityId: candidate.entityId,
|
|
158
|
+
entityName: candidate.entityName,
|
|
159
|
+
score: maxScore > 0 ? Math.round(candidate.rawScore / maxScore * 1e4) / 1e4 : 0,
|
|
160
|
+
rationale: `${candidate.matchCount} matching memor${candidate.matchCount === 1 ? "y" : "ies"} (topic co-occurrence${candidate.authorshipCount > 0 ? `, ${candidate.authorshipCount} with direct attribution` : ""})${candidate.lastSeen ? `; latest ${candidate.lastSeen}` : ""}`,
|
|
161
|
+
evidenceCount: candidate.matchCount,
|
|
162
|
+
lastSeen: candidate.lastSeen,
|
|
163
|
+
evidence: candidate.evidence
|
|
164
|
+
}));
|
|
165
|
+
return { topic: input.topic, results };
|
|
166
|
+
}
|
|
167
|
+
var WHO_KNOWS_MCP_TOOLS = [
|
|
168
|
+
{
|
|
169
|
+
// Registered as `engram.who_knows`; `withToolAliases` emits the canonical
|
|
170
|
+
// `remnic.who_knows` alias automatically (dual-naming invariant).
|
|
171
|
+
name: "engram.who_knows",
|
|
172
|
+
description: "Rank people/entities by demonstrated expertise for a topic (issue #2057). Deterministic scoring over entity mentions, attribution, importance, and recency; each hit carries evidence refs (ids/paths/timestamps). Empty topic is a validation error; a topic with no evidence returns an empty list.",
|
|
173
|
+
inputSchema: {
|
|
174
|
+
type: "object",
|
|
175
|
+
properties: {
|
|
176
|
+
topic: {
|
|
177
|
+
type: "string",
|
|
178
|
+
description: "Topic to rank expertise for. Required; non-empty."
|
|
179
|
+
},
|
|
180
|
+
limit: {
|
|
181
|
+
type: "integer",
|
|
182
|
+
minimum: 1,
|
|
183
|
+
maximum: WHO_KNOWS_MAX_LIMIT,
|
|
184
|
+
description: `Maximum hits to return (default ${WHO_KNOWS_DEFAULT_LIMIT}, max ${WHO_KNOWS_MAX_LIMIT}).`
|
|
185
|
+
},
|
|
186
|
+
namespace: {
|
|
187
|
+
type: "string",
|
|
188
|
+
description: "Optional namespace. Enforced against the caller's principal the same way recall is."
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
required: ["topic"],
|
|
192
|
+
additionalProperties: false
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
];
|
|
196
|
+
async function handleWhoKnowsHttpQuery(deps) {
|
|
197
|
+
const topicParam = deps.getParam("topic");
|
|
198
|
+
if (topicParam === null || topicParam.trim().length === 0) {
|
|
199
|
+
return {
|
|
200
|
+
status: 400,
|
|
201
|
+
body: {
|
|
202
|
+
error: "missing_topic",
|
|
203
|
+
code: "missing_topic",
|
|
204
|
+
message: "topic search parameter is required and must be non-empty"
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
let limit;
|
|
209
|
+
const limitParam = deps.getParam("limit");
|
|
210
|
+
if (limitParam !== null && limitParam !== "") {
|
|
211
|
+
const parsed = Number(limitParam);
|
|
212
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > WHO_KNOWS_MAX_LIMIT) {
|
|
213
|
+
return {
|
|
214
|
+
status: 400,
|
|
215
|
+
body: {
|
|
216
|
+
error: "invalid_limit",
|
|
217
|
+
code: "invalid_limit",
|
|
218
|
+
message: `limit expects an integer between 1 and ${WHO_KNOWS_MAX_LIMIT}`
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
limit = parsed;
|
|
223
|
+
}
|
|
224
|
+
const namespaceParam = deps.getParam("namespace");
|
|
225
|
+
const namespace = deps.resolveNamespace(namespaceParam && namespaceParam.length > 0 ? namespaceParam : void 0);
|
|
226
|
+
try {
|
|
227
|
+
return {
|
|
228
|
+
status: 200,
|
|
229
|
+
body: await deps.run({
|
|
230
|
+
topic: topicParam,
|
|
231
|
+
...limit !== void 0 ? { limit } : {},
|
|
232
|
+
...namespace !== void 0 ? { namespace } : {},
|
|
233
|
+
...deps.principal ? { authenticatedPrincipal: deps.principal } : {}
|
|
234
|
+
})
|
|
235
|
+
};
|
|
236
|
+
} catch (err) {
|
|
237
|
+
if (err instanceof EngramAccessInputError) {
|
|
238
|
+
return { status: 400, body: { error: "invalid_request", code: "invalid_request", message: err.message } };
|
|
239
|
+
}
|
|
240
|
+
throw err;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export {
|
|
245
|
+
WHO_KNOWS_DEFAULT_LIMIT,
|
|
246
|
+
WHO_KNOWS_MAX_LIMIT,
|
|
247
|
+
WHO_KNOWS_MAX_EVIDENCE,
|
|
248
|
+
WHO_KNOWS_AUTHORSHIP_BONUS,
|
|
249
|
+
loadWhoKnowsEntities,
|
|
250
|
+
validateWhoKnowsInput,
|
|
251
|
+
tokenizeTopic,
|
|
252
|
+
computeWhoKnows,
|
|
253
|
+
WHO_KNOWS_MCP_TOOLS,
|
|
254
|
+
handleWhoKnowsHttpQuery
|
|
255
|
+
};
|
|
256
|
+
//# sourceMappingURL=chunk-TKI2WOL5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/who-knows.ts"],"sourcesContent":["/**\n * `who_knows` — rank entities by demonstrated expertise for a topic\n * (issue #2057).\n *\n * Deterministic scoring over existing entity + fact data. No LLM, no QMD:\n * a single pass over the namespace-scoped corpus (`readAllMemories`) plus\n * entity files. Signals:\n *\n * 1. Entity mentions co-occurring with topic tokens (entityRef + name/alias\n * mention in matching memory content).\n * 2. Speaker/authorship attribution (\"Alice said/explained/…\") when present —\n * small multiplicative bonus.\n * 3. Recency as a tie-break only (per the issue): newer evidence ranks higher\n * when scores tie; entity id is the final stable key (total order).\n * 4. Existing importance + confidence frontmatter weight each evidence item.\n *\n * Pure functions live here so tests can exercise scoring without booting an\n * orchestrator; the access service supplies namespace-scoped data. MCP tool\n * definitions are exported for access-mcp.ts to spread into `tools/list`\n * (same pattern as `meetings/mcp-tools.ts`).\n */\n\nimport { EngramAccessInputError } from \"./access-errors.js\";\nimport type { McpTool } from \"./access-mcp.js\";\nimport { inferMemoryStatus } from \"./memory-lifecycle-ledger-utils.js\";\nimport { parseEntityFile } from \"./storage/entity-store.js\";\nimport type { MemoryFile, PluginConfig } from \"./types.js\";\n\n/** Default result count (issue #2057: \"small ranked list\"). */\nexport const WHO_KNOWS_DEFAULT_LIMIT = 5;\n/** Upper bound for `limit`. Rejects unbounded fan-out without silently clamping. */\nexport const WHO_KNOWS_MAX_LIMIT = 50;\n/** Evidence refs retained per hit. Independent of the result limit. */\nexport const WHO_KNOWS_MAX_EVIDENCE = 50;\n/** Multiplicative bonus for evidence with direct speaker attribution. */\nexport const WHO_KNOWS_AUTHORSHIP_BONUS = 1.5;\n\n/** Minimal storage surface `who_knows` needs — satisfied by `StorageManager`. */\nexport interface WhoKnowsStorage {\n readAllMemories(): Promise<MemoryFile[]>;\n listEntityNames(): Promise<string[]>;\n readEntity(name: string): Promise<string>;\n}\n\n/** Flattened entity input for scoring. `id` is the entity key (file stem). */\nexport interface WhoKnowsEntity {\n id: string;\n name: string;\n aliases: readonly string[];\n}\n\n/** Evidence reference — ids/paths/timestamps only, no raw content. */\nexport interface WhoKnowsEvidence {\n id: string;\n path: string;\n updated: string;\n}\n\nexport interface WhoKnowsHit {\n entityId: string;\n entityName: string | null;\n /** Normalized 0–1 relative to the top hit (top = 1). */\n score: number;\n rationale: string;\n evidenceCount: number;\n lastSeen: string | null;\n evidence: WhoKnowsEvidence[];\n}\n\nexport interface WhoKnowsResult {\n topic: string;\n results: WhoKnowsHit[];\n}\n\n/** Load all entities for a namespace-scoped storage as scoring input. */\nexport async function loadWhoKnowsEntities(\n storage: WhoKnowsStorage,\n entitySchemas?: PluginConfig[\"entitySchemas\"],\n): Promise<WhoKnowsEntity[]> {\n const entities: WhoKnowsEntity[] = [];\n for (const id of await storage.listEntityNames()) {\n const raw = await storage.readEntity(id);\n if (!raw) continue;\n try {\n const entity = parseEntityFile(raw, entitySchemas);\n entities.push({ id, name: entity.name, aliases: entity.aliases });\n } catch {\n // Unparseable entity files are skipped, not fatal — same tolerance as\n // the entityList surface (a bad file must not break ranking).\n }\n }\n return entities;\n}\n\n/** Validate topic + limit at every entrypoint. Shared by service/CLI/HTTP. */\nexport function validateWhoKnowsInput(topic: string, limit: number): void {\n if (topic.trim().length === 0) {\n throw new EngramAccessInputError(\"whoKnows: topic is required and must be non-empty\");\n }\n if (!Number.isInteger(limit) || limit < 1 || limit > WHO_KNOWS_MAX_LIMIT) {\n throw new EngramAccessInputError(\n `whoKnows: limit expects an integer between 1 and ${WHO_KNOWS_MAX_LIMIT}`,\n );\n}\n}\nconst STOPWORDS: Record<string, true> = {\n the: true, a: true, an: true, of: true, and: true, or: true, to: true, in: true, for: true,\n on: true, with: true, is: true, are: true, was: true, were: true, who: true, knows: true,\n know: true, about: true, at: true, by: true,\n};\n\n/** Lowercase alphanumeric topic tokens, stopwords dropped, deduplicated. */\nexport function tokenizeTopic(topic: string): string[] {\n const tokens = topic\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((token) => token.length >= 2 && STOPWORDS[token] !== true);\n return [...new Set(tokens)];\n}\n\nconst ATTRIBUTION_VERBS =\n \"said|says|mentioned|noted|explained|recommended|suggested|proposed|wrote|asked|answered|demonstrated|designed|built|debugged|fixed\";\n\nfunction escapeRegex(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction wordMatcher(term: string): RegExp {\n return new RegExp(`\\\\b${escapeRegex(term.toLowerCase())}\\\\b`);\n}\n\ninterface ScoredCandidate {\n entityId: string;\n entityName: string | null;\n rawScore: number;\n evidence: WhoKnowsEvidence[];\n matchCount: number;\n authorshipCount: number;\n lastSeen: string | null;\n}\n\n/**\n * Deterministic ranking. Pure: same inputs → same output, total order via\n * (score desc, lastSeen desc, entityId asc) so ties never depend on scan\n * order (sort-stability rule).\n */\nexport function computeWhoKnows(input: {\n topic: string;\n limit: number;\n memories: readonly MemoryFile[];\n entities: readonly WhoKnowsEntity[];\n}): WhoKnowsResult {\n const topicTokens = tokenizeTopic(input.topic);\n const byId = new Map(input.entities.map((entity) => [entity.id, entity]));\n\n // Multi-word names/aliases must match as phrases; single words as tokens.\n const mentionMatchers: Array<{ entityId: string; matcher: RegExp }> = [];\n const authorshipMatchers: Array<{ entityId: string; matcher: RegExp }> = [];\n for (const entity of input.entities) {\n for (const term of [entity.name, ...entity.aliases]) {\n const clean = term.trim().toLowerCase();\n if (clean.length < 2) continue;\n mentionMatchers.push({ entityId: entity.id, matcher: wordMatcher(clean) });\n const possessive = clean.replace(/'/g, \"\");\n authorshipMatchers.push({\n entityId: entity.id,\n matcher: new RegExp(\n `\\\\b${escapeRegex(possessive)}(?:'s)?\\\\b[^.!?]{0,40}\\\\b(?:${ATTRIBUTION_VERBS})\\\\b`,\n ),\n });\n }\n }\n\n const candidates = new Map<string, ScoredCandidate>();\n const credit = (entityId: string, memory: MemoryFile, weight: number, authorship: boolean): void => {\n let candidate = candidates.get(entityId);\n if (!candidate) {\n candidate = {\n entityId,\n entityName: byId.get(entityId)?.name ?? null,\n rawScore: 0,\n evidence: [],\n matchCount: 0,\n authorshipCount: 0,\n lastSeen: null,\n };\n candidates.set(entityId, candidate);\n }\n candidate.rawScore += weight;\n candidate.matchCount += 1;\n candidate.authorshipCount += authorship ? 1 : 0;\n const updated = memory.frontmatter.updated || memory.frontmatter.created;\n if (updated && (!candidate.lastSeen || updated > candidate.lastSeen)) {\n candidate.lastSeen = updated;\n }\n if (candidate.evidence.length < WHO_KNOWS_MAX_EVIDENCE) {\n candidate.evidence.push({\n id: memory.frontmatter.id,\n path: memory.path,\n updated: memory.frontmatter.updated || memory.frontmatter.created,\n });\n }\n };\n\n for (const memory of input.memories) {\n if (inferMemoryStatus(memory.frontmatter, memory.path) !== \"active\") continue;\n const haystack = `${memory.content}\\n${memory.frontmatter.tags.join(\" \")}`.toLowerCase();\n const matched = topicTokens.filter((token) => haystack.includes(token));\n if (matched.length === 0) continue;\n const coverage = matched.length / topicTokens.length;\n const importance = memory.frontmatter.importance?.score ?? 0.5;\n const confidence = memory.frontmatter.confidence ?? 0.5;\n let weight = coverage * (0.5 + 0.5 * importance) * confidence;\n\n const attributed = new Set<string>();\n // entityRef counts even when the entity file is missing — the hit then\n // carries the ref id with a null display name (missing-name case).\n if (memory.frontmatter.entityRef) attributed.add(memory.frontmatter.entityRef);\n for (const { entityId, matcher } of mentionMatchers) {\n if (matcher.test(haystack)) attributed.add(entityId);\n }\n if (attributed.size === 0) continue;\n\n // Attribution is per entity: \"Alice explained X with Bob\" credits only\n // Alice with authorship — Bob is a co-mention, not the speaker.\n const attributedAuthors = new Set<string>();\n for (const { entityId, matcher } of authorshipMatchers) {\n if (attributed.has(entityId) && matcher.test(haystack)) attributedAuthors.add(entityId);\n }\n for (const entityId of attributed) {\n const authorship = attributedAuthors.has(entityId);\n credit(entityId, memory, authorship ? weight * WHO_KNOWS_AUTHORSHIP_BONUS : weight, authorship);\n }\n }\n\n const ranked = [...candidates.values()].sort((a, b) => {\n if (b.rawScore !== a.rawScore) return b.rawScore - a.rawScore;\n const aSeen = a.lastSeen ?? \"\";\n const bSeen = b.lastSeen ?? \"\";\n if (aSeen !== bSeen) return aSeen < bSeen ? 1 : -1;\n return a.entityId < b.entityId ? -1 : a.entityId > b.entityId ? 1 : 0;\n });\n const top = ranked.slice(0, input.limit);\n const maxScore = top.length > 0 ? top[0].rawScore : 0;\n const results: WhoKnowsHit[] = top.map((candidate) => ({\n entityId: candidate.entityId,\n entityName: candidate.entityName,\n score: maxScore > 0 ? Math.round((candidate.rawScore / maxScore) * 10000) / 10000 : 0,\n rationale:\n `${candidate.matchCount} matching memor${candidate.matchCount === 1 ? \"y\" : \"ies\"}` +\n ` (topic co-occurrence${candidate.authorshipCount > 0 ? `, ${candidate.authorshipCount} with direct attribution` : \"\"})` +\n `${candidate.lastSeen ? `; latest ${candidate.lastSeen}` : \"\"}`,\n evidenceCount: candidate.matchCount,\n lastSeen: candidate.lastSeen,\n evidence: candidate.evidence,\n }));\n\n return { topic: input.topic, results };\n}\n\n// ---------------------------------------------------------------------------\n// MCP tool definition (spread into access-mcp.ts tools/list — see\n// MEETINGS_MCP_TOOLS precedent; the type-only import keeps this cycle-free).\n// ---------------------------------------------------------------------------\n\nexport const WHO_KNOWS_MCP_TOOLS: McpTool[] = [\n {\n // Registered as `engram.who_knows`; `withToolAliases` emits the canonical\n // `remnic.who_knows` alias automatically (dual-naming invariant).\n name: \"engram.who_knows\",\n description:\n \"Rank people/entities by demonstrated expertise for a topic (issue #2057). Deterministic scoring over entity mentions, attribution, importance, and recency; each hit carries evidence refs (ids/paths/timestamps). Empty topic is a validation error; a topic with no evidence returns an empty list.\",\n inputSchema: {\n type: \"object\",\n properties: {\n topic: {\n type: \"string\",\n description: \"Topic to rank expertise for. Required; non-empty.\",\n },\n limit: {\n type: \"integer\",\n minimum: 1,\n maximum: WHO_KNOWS_MAX_LIMIT,\n description: `Maximum hits to return (default ${WHO_KNOWS_DEFAULT_LIMIT}, max ${WHO_KNOWS_MAX_LIMIT}).`,\n },\n namespace: {\n type: \"string\",\n description:\n \"Optional namespace. Enforced against the caller's principal the same way recall is.\",\n },\n },\n required: [\"topic\"],\n additionalProperties: false,\n },\n },\n];\n\n// ---------------------------------------------------------------------------\n// HTTP query handling (called from access-http.ts so the route stays thin —\n// that file is size-grandfathered).\n// ---------------------------------------------------------------------------\n\nexport interface WhoKnowsHttpOutcome {\n status: number;\n body: unknown;\n}\n\nexport async function handleWhoKnowsHttpQuery(deps: {\n getParam: (name: string) => string | null;\n resolveNamespace: (namespace: string | undefined) => string | undefined;\n principal?: string;\n run: (request: { topic: string; limit?: number; namespace?: string; authenticatedPrincipal?: string }) => Promise<WhoKnowsResult>;\n}): Promise<WhoKnowsHttpOutcome> {\n const topicParam = deps.getParam(\"topic\");\n if (topicParam === null || topicParam.trim().length === 0) {\n return {\n status: 400,\n body: {\n error: \"missing_topic\",\n code: \"missing_topic\",\n message: \"topic search parameter is required and must be non-empty\",\n },\n };\n }\n let limit: number | undefined;\n const limitParam = deps.getParam(\"limit\");\n if (limitParam !== null && limitParam !== \"\") {\n const parsed = Number(limitParam);\n if (!Number.isInteger(parsed) || parsed < 1 || parsed > WHO_KNOWS_MAX_LIMIT) {\n return {\n status: 400,\n body: {\n error: \"invalid_limit\",\n code: \"invalid_limit\",\n message: `limit expects an integer between 1 and ${WHO_KNOWS_MAX_LIMIT}`,\n },\n };\n }\n limit = parsed;\n }\n const namespaceParam = deps.getParam(\"namespace\");\n // Always resolve (and allow-list check) the effective namespace, even when\n // the param is omitted — the implicit default namespace is still a\n // namespace every other GET route gates the same way.\n const namespace = deps.resolveNamespace(namespaceParam && namespaceParam.length > 0 ? namespaceParam : undefined);\n try {\n return {\n status: 200,\n body: await deps.run({\n topic: topicParam,\n ...(limit !== undefined ? { limit } : {}),\n ...(namespace !== undefined ? { namespace } : {}),\n ...(deps.principal ? { authenticatedPrincipal: deps.principal } : {}),\n }),\n };\n } catch (err) {\n // Input validation (including namespace ACL) is a 400; backend faults\n // bubble to the global handler so they return 500 and get logged.\n if (err instanceof EngramAccessInputError) {\n return { status: 400, body: { error: \"invalid_request\", code: \"invalid_request\", message: err.message } };\n }\n throw err;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WHO_KNOWS_DEFAULT_LIMIT,
|
|
3
|
+
WHO_KNOWS_MAX_LIMIT,
|
|
4
|
+
validateWhoKnowsInput
|
|
5
|
+
} from "./chunk-TKI2WOL5.js";
|
|
6
|
+
|
|
7
|
+
// src/who-knows-cli.ts
|
|
8
|
+
function extractWhoKnowsRawArgs(rest) {
|
|
9
|
+
const VALUE_FLAGS = { "--limit": true, "--namespace": true };
|
|
10
|
+
const positional = [];
|
|
11
|
+
const options = {};
|
|
12
|
+
for (let i = 0; i < rest.length; i++) {
|
|
13
|
+
const token = rest[i];
|
|
14
|
+
if (token.startsWith("--")) {
|
|
15
|
+
if (token === "--json") {
|
|
16
|
+
options.json = true;
|
|
17
|
+
} else if (VALUE_FLAGS[token]) {
|
|
18
|
+
const value = rest[i + 1];
|
|
19
|
+
if (value === void 0 || value.startsWith("--")) {
|
|
20
|
+
throw new Error(`who-knows: ${token} expects a value`);
|
|
21
|
+
}
|
|
22
|
+
options[token.slice(2)] = value;
|
|
23
|
+
i += 1;
|
|
24
|
+
} else {
|
|
25
|
+
throw new Error(`who-knows: unknown option ${token} (expected --limit, --namespace, or --json)`);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
positional.push(token);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { topic: positional.join(" ").trim(), options };
|
|
32
|
+
}
|
|
33
|
+
function parseWhoKnowsCliOptions(rawTopic, options) {
|
|
34
|
+
if (typeof rawTopic !== "string" || rawTopic.trim().length === 0) {
|
|
35
|
+
throw new Error("who-knows: topic is required and must be non-empty");
|
|
36
|
+
}
|
|
37
|
+
let limit = WHO_KNOWS_DEFAULT_LIMIT;
|
|
38
|
+
if (options.limit !== void 0) {
|
|
39
|
+
const parsed = typeof options.limit === "number" ? options.limit : Number(options.limit);
|
|
40
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > WHO_KNOWS_MAX_LIMIT) {
|
|
41
|
+
throw new Error(`who-knows: --limit expects an integer between 1 and ${WHO_KNOWS_MAX_LIMIT}`);
|
|
42
|
+
}
|
|
43
|
+
limit = parsed;
|
|
44
|
+
}
|
|
45
|
+
const namespace = typeof options.namespace === "string" && options.namespace.trim().length > 0 ? options.namespace.trim() : void 0;
|
|
46
|
+
validateWhoKnowsInput(rawTopic, limit);
|
|
47
|
+
return { topic: rawTopic.trim(), limit, namespace, json: options.json === true };
|
|
48
|
+
}
|
|
49
|
+
function renderWhoKnowsJson(result) {
|
|
50
|
+
return JSON.stringify(result, null, 2);
|
|
51
|
+
}
|
|
52
|
+
function renderWhoKnowsText(result) {
|
|
53
|
+
if (result.results.length === 0) {
|
|
54
|
+
return `who knows "${result.topic}": no evidence found`;
|
|
55
|
+
}
|
|
56
|
+
const lines = [`who knows "${result.topic}" (top ${result.results.length})`];
|
|
57
|
+
result.results.forEach((hit, index) => {
|
|
58
|
+
const name = hit.entityName || hit.entityId;
|
|
59
|
+
lines.push(`${index + 1}. ${name} [${hit.entityId}] \u2014 score ${hit.score.toFixed(4)} \u2014 ${hit.rationale}`);
|
|
60
|
+
for (const ref of hit.evidence) {
|
|
61
|
+
lines.push(` - ${ref.id} (${ref.path}) updated ${ref.updated}`);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return lines.join("\n");
|
|
65
|
+
}
|
|
66
|
+
function renderWhoKnows(result, json) {
|
|
67
|
+
return json ? renderWhoKnowsJson(result) : renderWhoKnowsText(result);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
extractWhoKnowsRawArgs,
|
|
72
|
+
parseWhoKnowsCliOptions,
|
|
73
|
+
renderWhoKnowsJson,
|
|
74
|
+
renderWhoKnowsText,
|
|
75
|
+
renderWhoKnows
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=chunk-TY35YQ6E.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/who-knows-cli.ts"],"sourcesContent":["/**\n * Input-validation + rendering helpers for the `remnic who-knows` CLI\n * command (issue #2057). Extracted so validation paths can be unit-tested\n * without booting an orchestrator (same pattern as `recall-xray-cli.ts`).\n *\n * Rules 14 + 51: bare `--limit`, non-integer or out-of-range values, and an\n * empty topic throw listed-options errors — never silent defaults.\n */\n\nimport {\n validateWhoKnowsInput,\n WHO_KNOWS_DEFAULT_LIMIT,\n WHO_KNOWS_MAX_LIMIT,\n type WhoKnowsResult,\n} from \"./who-knows.js\";\n\nexport interface ParsedWhoKnowsCliOptions {\n topic: string;\n limit: number;\n namespace?: string;\n json: boolean;\n}\n\n/** Split raw argv into the positional topic and a flag bag. Value flags error when bare. */\nexport function extractWhoKnowsRawArgs(rest: string[]): {\n topic: string;\n options: Record<string, unknown>;\n} {\n const VALUE_FLAGS: Record<string, true> = { \"--limit\": true, \"--namespace\": true };\n const positional: string[] = [];\n const options: Record<string, unknown> = {};\n for (let i = 0; i < rest.length; i++) {\n const token = rest[i];\n if (token.startsWith(\"--\")) {\n if (token === \"--json\") {\n options.json = true;\n } else if (VALUE_FLAGS[token]) {\n const value = rest[i + 1];\n if (value === undefined || value.startsWith(\"--\")) {\n throw new Error(`who-knows: ${token} expects a value`);\n }\n options[token.slice(2)] = value;\n i += 1;\n } else {\n throw new Error(`who-knows: unknown option ${token} (expected --limit, --namespace, or --json)`);\n }\n } else {\n positional.push(token);\n }\n }\n return { topic: positional.join(\" \").trim(), options };\n}\n\n/** Validate the full option bag. Throws listed-options errors for bad input. */\nexport function parseWhoKnowsCliOptions(rawTopic: unknown, options: Record<string, unknown>): ParsedWhoKnowsCliOptions {\n if (typeof rawTopic !== \"string\" || rawTopic.trim().length === 0) {\n throw new Error(\"who-knows: topic is required and must be non-empty\");\n }\n let limit = WHO_KNOWS_DEFAULT_LIMIT;\n if (options.limit !== undefined) {\n const parsed = typeof options.limit === \"number\" ? options.limit : Number(options.limit);\n if (!Number.isInteger(parsed) || parsed < 1 || parsed > WHO_KNOWS_MAX_LIMIT) {\n throw new Error(`who-knows: --limit expects an integer between 1 and ${WHO_KNOWS_MAX_LIMIT}`);\n }\n limit = parsed;\n }\n const namespace = typeof options.namespace === \"string\" && options.namespace.trim().length > 0\n ? options.namespace.trim()\n : undefined;\n validateWhoKnowsInput(rawTopic, limit);\n return { topic: rawTopic.trim(), limit, namespace, json: options.json === true };\n}\n\nexport function renderWhoKnowsJson(result: WhoKnowsResult): string {\n return JSON.stringify(result, null, 2);\n}\n\nexport function renderWhoKnowsText(result: WhoKnowsResult): string {\n if (result.results.length === 0) {\n return `who knows \"${result.topic}\": no evidence found`;\n }\n const lines = [`who knows \"${result.topic}\" (top ${result.results.length})`];\n result.results.forEach((hit, index) => {\n const name = hit.entityName || hit.entityId;\n lines.push(`${index + 1}. ${name} [${hit.entityId}] — score ${hit.score.toFixed(4)} — ${hit.rationale}`);\n for (const ref of hit.evidence) {\n lines.push(` - ${ref.id} (${ref.path}) updated ${ref.updated}`);\n }\n });\n return lines.join(\"\\n\");\n}\n\nexport function renderWhoKnows(result: WhoKnowsResult, json: boolean): string {\n return json ? renderWhoKnowsJson(result) : renderWhoKnowsText(result);\n}\n\n"],"mappings":";;;;;;;AAwBO,SAAS,uBAAuB,MAGrC;AACA,QAAM,cAAoC,EAAE,WAAW,MAAM,eAAe,KAAK;AACjF,QAAM,aAAuB,CAAC;AAC9B,QAAM,UAAmC,CAAC;AAC1C,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,QAAQ,KAAK,CAAC;AACpB,QAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,UAAI,UAAU,UAAU;AACtB,gBAAQ,OAAO;AAAA,MACjB,WAAW,YAAY,KAAK,GAAG;AAC7B,cAAM,QAAQ,KAAK,IAAI,CAAC;AACxB,YAAI,UAAU,UAAa,MAAM,WAAW,IAAI,GAAG;AACjD,gBAAM,IAAI,MAAM,cAAc,KAAK,kBAAkB;AAAA,QACvD;AACA,gBAAQ,MAAM,MAAM,CAAC,CAAC,IAAI;AAC1B,aAAK;AAAA,MACP,OAAO;AACL,cAAM,IAAI,MAAM,6BAA6B,KAAK,6CAA6C;AAAA,MACjG;AAAA,IACF,OAAO;AACL,iBAAW,KAAK,KAAK;AAAA,IACvB;AAAA,EACF;AACA,SAAO,EAAE,OAAO,WAAW,KAAK,GAAG,EAAE,KAAK,GAAG,QAAQ;AACvD;AAGO,SAAS,wBAAwB,UAAmB,SAA4D;AACrH,MAAI,OAAO,aAAa,YAAY,SAAS,KAAK,EAAE,WAAW,GAAG;AAChE,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AACA,MAAI,QAAQ;AACZ,MAAI,QAAQ,UAAU,QAAW;AAC/B,UAAM,SAAS,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,OAAO,QAAQ,KAAK;AACvF,QAAI,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS,KAAK,SAAS,qBAAqB;AAC3E,YAAM,IAAI,MAAM,uDAAuD,mBAAmB,EAAE;AAAA,IAC9F;AACA,YAAQ;AAAA,EACV;AACA,QAAM,YAAY,OAAO,QAAQ,cAAc,YAAY,QAAQ,UAAU,KAAK,EAAE,SAAS,IACzF,QAAQ,UAAU,KAAK,IACvB;AACJ,wBAAsB,UAAU,KAAK;AACrC,SAAO,EAAE,OAAO,SAAS,KAAK,GAAG,OAAO,WAAW,MAAM,QAAQ,SAAS,KAAK;AACjF;AAEO,SAAS,mBAAmB,QAAgC;AACjE,SAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AACvC;AAEO,SAAS,mBAAmB,QAAgC;AACjE,MAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,WAAO,cAAc,OAAO,KAAK;AAAA,EACnC;AACA,QAAM,QAAQ,CAAC,cAAc,OAAO,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;AAC3E,SAAO,QAAQ,QAAQ,CAAC,KAAK,UAAU;AACrC,UAAM,OAAO,IAAI,cAAc,IAAI;AACnC,UAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,KAAK,IAAI,QAAQ,kBAAa,IAAI,MAAM,QAAQ,CAAC,CAAC,WAAM,IAAI,SAAS,EAAE;AACvG,eAAW,OAAO,IAAI,UAAU;AAC9B,YAAM,KAAK,QAAQ,IAAI,EAAE,KAAK,IAAI,IAAI,aAAa,IAAI,OAAO,EAAE;AAAA,IAClE;AAAA,EACF,CAAC;AACD,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,eAAe,QAAwB,MAAuB;AAC5E,SAAO,OAAO,mBAAmB,MAAM,IAAI,mBAAmB,MAAM;AACtE;","names":[]}
|
|
@@ -939,6 +939,27 @@ function parseLocationConfig(raw) {
|
|
|
939
939
|
return { enabled, timezone, syncDays, retainCoordinates, sources };
|
|
940
940
|
}
|
|
941
941
|
|
|
942
|
+
// src/okf/config.ts
|
|
943
|
+
var DEFAULT_OKF_CONFIG = Object.freeze({
|
|
944
|
+
conformanceEnabled: true,
|
|
945
|
+
sweepEnabled: false
|
|
946
|
+
});
|
|
947
|
+
function parseOkfConfig(raw) {
|
|
948
|
+
if (raw === void 0 || raw === null) return { ...DEFAULT_OKF_CONFIG };
|
|
949
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
950
|
+
throw new Error(
|
|
951
|
+
`okf must be an object (got ${JSON.stringify(raw)}). Use okf: { conformanceEnabled: false } to opt out; omit the key for defaults.`
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
const record = raw;
|
|
955
|
+
const conformance = coerceBooleanLike(record.conformanceEnabled, "okf.conformanceEnabled");
|
|
956
|
+
const sweep = coerceBooleanLike(record.sweepEnabled, "okf.sweepEnabled");
|
|
957
|
+
return {
|
|
958
|
+
conformanceEnabled: conformance ?? DEFAULT_OKF_CONFIG.conformanceEnabled,
|
|
959
|
+
sweepEnabled: sweep ?? DEFAULT_OKF_CONFIG.sweepEnabled
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
|
|
942
963
|
// src/chat/chat-config.ts
|
|
943
964
|
var DEFAULT_CHAT_CONFIG = {
|
|
944
965
|
enabled: false,
|
|
@@ -2566,6 +2587,7 @@ function parseConfig(raw, rawOperatorConfig, runtimeSet) {
|
|
|
2566
2587
|
converge: parseConvergeConfig(cfg.converge),
|
|
2567
2588
|
wearables,
|
|
2568
2589
|
meetings,
|
|
2590
|
+
okf: parseOkfConfig(cfg.okf),
|
|
2569
2591
|
activity,
|
|
2570
2592
|
location,
|
|
2571
2593
|
provenance,
|
|
@@ -3994,4 +4016,4 @@ export {
|
|
|
3994
4016
|
VALID_MEMORY_CATEGORIES,
|
|
3995
4017
|
parseConfig
|
|
3996
4018
|
};
|
|
3997
|
-
//# sourceMappingURL=chunk-
|
|
4019
|
+
//# sourceMappingURL=chunk-UMDZXW5J.js.map
|