@remnic/core 9.64.0 → 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 +24 -23
- package/dist/access-authorization-probe.d.ts +12 -11
- package/dist/access-authorization-probe.js +25 -24
- package/dist/access-boundary.d.ts +13 -12
- package/dist/access-boundary.js +24 -23
- package/dist/access-cli.js +74 -72
- 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 +24 -23
- 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 +26 -25
- package/dist/access-http.d.ts +13 -12
- package/dist/access-http.js +41 -40
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +24 -23
- package/dist/access-lcm-surface.d.ts +12 -11
- package/dist/access-lcm-surface.js +24 -23
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +12 -186
- package/dist/access-mcp.js +33 -32
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-CrF0FKaz.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 +24 -23
- package/dist/access-observe-write-surface.d.ts +12 -11
- package/dist/access-observe-write-surface.js +24 -23
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-operations-batch.js +27 -26
- package/dist/access-operations.d.ts +13 -12
- package/dist/access-operations.js +30 -29
- package/dist/access-recall-concurrency.d.ts +12 -11
- package/dist/access-recall-concurrency.js +24 -23
- package/dist/access-recall-response.d.ts +12 -11
- package/dist/access-recall-response.js +24 -23
- package/dist/access-recall-surface.d.ts +12 -11
- package/dist/access-recall-surface.js +24 -23
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-BqF4UK8Z.d.ts → access-service-BKtdXnyk.d.ts} +294 -12
- package/dist/access-service-helpers.d.ts +12 -11
- package/dist/access-service.d.ts +12 -11
- package/dist/access-service.js +24 -23
- package/dist/access-surface-catalog.d.ts +12 -11
- package/dist/access-surface-catalog.js +28 -25
- 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/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/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{catalog-C0KIwZqR.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-BTUIHRRR.js → chunk-246HFJVG.js} +2 -2
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-5SZ6CLGJ.js → chunk-2QI2JBLQ.js} +360 -238
- package/dist/chunk-2QI2JBLQ.js.map +1 -0
- package/dist/{chunk-6NMZXEJ7.js → chunk-3A46U7XG.js} +2 -2
- package/dist/{chunk-S6KMN6MJ.js → chunk-3LOQN3TO.js} +10 -5
- package/dist/chunk-3LOQN3TO.js.map +1 -0
- package/dist/{chunk-Z3Q5I5F6.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-KG2CT762.js → chunk-6LTCUN3T.js} +2 -2
- package/dist/{chunk-UUYQWKHO.js → chunk-7BVO64UC.js} +2 -2
- package/dist/{chunk-X6HNXVXS.js → chunk-7V3AZWWZ.js} +4 -4
- package/dist/{chunk-EHC3FIJ4.js → chunk-A2IBK3TG.js} +2 -2
- package/dist/{chunk-6BV6ZZZA.js → chunk-C6AKYOFO.js} +2 -2
- package/dist/{chunk-7ML7STOD.js → chunk-CKZHKFY3.js} +3 -3
- package/dist/{chunk-CUDSA46O.js → chunk-CUIAHZPZ.js} +2 -2
- package/dist/{chunk-QFPX7QZG.js → chunk-DA2O3F5V.js} +25 -11
- package/dist/chunk-DA2O3F5V.js.map +1 -0
- package/dist/{chunk-CTD5CPD2.js → chunk-DC4FJY2G.js} +22 -7
- package/dist/{chunk-CTD5CPD2.js.map → chunk-DC4FJY2G.js.map} +1 -1
- package/dist/{chunk-2BRCV2IV.js → chunk-DG6MJD7W.js} +2 -2
- package/dist/{chunk-YGSDWO3U.js → chunk-DHKV6E4A.js} +2 -2
- package/dist/{chunk-DZFPHARJ.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-BPLPGOUJ.js → chunk-GVRLED7R.js} +2 -2
- package/dist/{chunk-YINSSARY.js → chunk-H5CGAD7L.js} +1 -1
- package/dist/{chunk-QICOU4RY.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-WQ6TRWAE.js → chunk-JCSUNXYJ.js} +3 -3
- package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-6IKXAAJI.js → chunk-KRPE7ANR.js} +2 -2
- package/dist/{chunk-FEP45MYY.js → chunk-LOETWOEB.js} +2 -2
- package/dist/{chunk-4IIDTPSK.js → chunk-LZKCMK3U.js} +2 -2
- package/dist/{chunk-ML4MI2RR.js → chunk-MJRVF7SF.js} +29 -28
- 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-BTBAHTQ5.js → chunk-NO7B6DRB.js} +2 -2
- package/dist/{chunk-G5F4MXXC.js → chunk-ON2P3SHG.js} +2 -2
- package/dist/{chunk-2Q4UAPLD.js → chunk-OQIRBGUU.js} +4 -4
- package/dist/{chunk-PQODT53H.js → chunk-PE76XIDM.js} +3 -3
- package/dist/{chunk-MVIYRRVJ.js → chunk-PMVPCZJZ.js} +5 -5
- package/dist/{chunk-CK3DZ6OE.js → chunk-PVIXAMWM.js} +2 -2
- package/dist/{chunk-BB2LH5JM.js → chunk-RNORDDD6.js} +11 -1
- package/dist/chunk-RNORDDD6.js.map +1 -0
- package/dist/{chunk-HZXO2CJ6.js → chunk-RWLRKMZK.js} +2 -2
- package/dist/{chunk-SYU5JOBQ.js → chunk-SB6YBB2V.js} +2 -2
- package/dist/{chunk-3F3CVVDS.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-R7XE5ZUR.js → chunk-UIYYS2YI.js} +2 -2
- package/dist/{chunk-ZWYXSF2T.js → chunk-UMDZXW5J.js} +118 -4
- package/dist/chunk-UMDZXW5J.js.map +1 -0
- package/dist/{chunk-G5OB4XZX.js → chunk-VANZKHTN.js} +4 -4
- package/dist/{chunk-QATILW4B.js → chunk-VLES5S4K.js} +271 -62
- package/dist/chunk-VLES5S4K.js.map +1 -0
- package/dist/{chunk-AR253JBM.js → chunk-VRYEXPRX.js} +1 -1
- package/dist/chunk-VRYEXPRX.js.map +1 -0
- package/dist/{chunk-7DRSWPUV.js → chunk-VUP47UJI.js} +3 -3
- package/dist/{chunk-65NQFK7D.js → chunk-WBM5NR4E.js} +2 -2
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-GIMQJ5RX.js → chunk-XACYILRA.js} +49 -14
- package/dist/chunk-XACYILRA.js.map +1 -0
- package/dist/{chunk-63JMI45N.js → chunk-XBRGJJK7.js} +2 -2
- package/dist/{chunk-WCWIV2JH.js → chunk-XH4IQVTN.js} +2 -2
- package/dist/{chunk-77E7LLMV.js → chunk-XZUCNVGE.js} +8 -8
- package/dist/{chunk-LJQGQUNS.js → chunk-YFQTDE7N.js} +2 -2
- package/dist/{chunk-5OOTHWGJ.js → chunk-YXGU3MDQ.js} +2 -2
- package/dist/{chunk-SRLQROQJ.js → chunk-Z6CJLYXT.js} +4 -4
- package/dist/{chunk-Z4UPRZR6.js → chunk-ZSYE2QVJ.js} +2 -2
- package/dist/{cli-BX0O688c.d.ts → cli-CLvBewKf.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +57 -56
- 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-Cph4PnBe.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 +25 -24
- 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 +13 -13
- 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 +33 -24
- package/dist/index.js +120 -84
- 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-BNq31xpo.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-CBuUOP2J.d.ts → orchestrator-6fPa2l9x.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +74 -72
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CW_Q4WvX.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-BeJ1_JI1.d.ts → public-http-BT36aBb-.d.ts} +1 -1
- package/dist/{qmd-q-cAzYuC.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/{scope-profiles-CIr4mXgp.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-BZ6J46j-.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-CCl4iyyY.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 +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +12 -12
- package/dist/{storage-BPXmJKIt.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 +27 -26
- 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/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-CltSWcND.d.ts → types-BP5MC8UU.d.ts} +34 -8
- 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 +7 -7
- package/src/index.ts +3 -0
- package/src/location/cli.ts +163 -0
- package/src/location/config.test.ts +75 -0
- package/src/location/config.ts +105 -0
- package/src/location/intervals.test.ts +202 -0
- package/src/location/intervals.ts +221 -0
- package/src/location/parse-companions.ts +12 -0
- package/src/location/pipeline.test.ts +324 -0
- package/src/location/pipeline.ts +245 -0
- package/src/location/recall-exclusion.test.ts +36 -0
- package/src/location/registry.test.ts +74 -0
- package/src/location/registry.ts +54 -0
- package/src/location/store.test.ts +170 -0
- package/src/location/store.ts +478 -0
- package/src/location/types.ts +95 -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/orchestration/generic-recall-paths.ts +17 -0
- package/src/orchestration/orchestrator-helpers.ts +22 -0
- package/src/orchestration/qmd-result-resolver.ts +1 -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 +6 -8
- 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-5SZ6CLGJ.js.map +0 -1
- package/dist/chunk-AR253JBM.js.map +0 -1
- package/dist/chunk-BB2LH5JM.js.map +0 -1
- package/dist/chunk-GIMQJ5RX.js.map +0 -1
- package/dist/chunk-HIEWDJ2O.js.map +0 -1
- package/dist/chunk-ML4MI2RR.js.map +0 -1
- package/dist/chunk-QATILW4B.js.map +0 -1
- package/dist/chunk-QFPX7QZG.js.map +0 -1
- package/dist/chunk-S6KMN6MJ.js.map +0 -1
- package/dist/chunk-VD2OT77P.js.map +0 -1
- package/dist/chunk-ZWYXSF2T.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{chunk-BTUIHRRR.js.map → chunk-246HFJVG.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-6NMZXEJ7.js.map → chunk-3A46U7XG.js.map} +0 -0
- /package/dist/{chunk-Z3Q5I5F6.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-KG2CT762.js.map → chunk-6LTCUN3T.js.map} +0 -0
- /package/dist/{chunk-UUYQWKHO.js.map → chunk-7BVO64UC.js.map} +0 -0
- /package/dist/{chunk-X6HNXVXS.js.map → chunk-7V3AZWWZ.js.map} +0 -0
- /package/dist/{chunk-EHC3FIJ4.js.map → chunk-A2IBK3TG.js.map} +0 -0
- /package/dist/{chunk-6BV6ZZZA.js.map → chunk-C6AKYOFO.js.map} +0 -0
- /package/dist/{chunk-7ML7STOD.js.map → chunk-CKZHKFY3.js.map} +0 -0
- /package/dist/{chunk-CUDSA46O.js.map → chunk-CUIAHZPZ.js.map} +0 -0
- /package/dist/{chunk-2BRCV2IV.js.map → chunk-DG6MJD7W.js.map} +0 -0
- /package/dist/{chunk-YGSDWO3U.js.map → chunk-DHKV6E4A.js.map} +0 -0
- /package/dist/{chunk-DZFPHARJ.js.map → chunk-EJDLQRUO.js.map} +0 -0
- /package/dist/{chunk-BPLPGOUJ.js.map → chunk-GVRLED7R.js.map} +0 -0
- /package/dist/{chunk-YINSSARY.js.map → chunk-H5CGAD7L.js.map} +0 -0
- /package/dist/{chunk-QICOU4RY.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-WQ6TRWAE.js.map → chunk-JCSUNXYJ.js.map} +0 -0
- /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-6IKXAAJI.js.map → chunk-KRPE7ANR.js.map} +0 -0
- /package/dist/{chunk-FEP45MYY.js.map → chunk-LOETWOEB.js.map} +0 -0
- /package/dist/{chunk-4IIDTPSK.js.map → chunk-LZKCMK3U.js.map} +0 -0
- /package/dist/{chunk-K547KS3X.js.map → chunk-ML3U4KPR.js.map} +0 -0
- /package/dist/{chunk-BTBAHTQ5.js.map → chunk-NO7B6DRB.js.map} +0 -0
- /package/dist/{chunk-G5F4MXXC.js.map → chunk-ON2P3SHG.js.map} +0 -0
- /package/dist/{chunk-2Q4UAPLD.js.map → chunk-OQIRBGUU.js.map} +0 -0
- /package/dist/{chunk-PQODT53H.js.map → chunk-PE76XIDM.js.map} +0 -0
- /package/dist/{chunk-MVIYRRVJ.js.map → chunk-PMVPCZJZ.js.map} +0 -0
- /package/dist/{chunk-CK3DZ6OE.js.map → chunk-PVIXAMWM.js.map} +0 -0
- /package/dist/{chunk-HZXO2CJ6.js.map → chunk-RWLRKMZK.js.map} +0 -0
- /package/dist/{chunk-SYU5JOBQ.js.map → chunk-SB6YBB2V.js.map} +0 -0
- /package/dist/{chunk-3F3CVVDS.js.map → chunk-SHQFYZTD.js.map} +0 -0
- /package/dist/{chunk-R7XE5ZUR.js.map → chunk-UIYYS2YI.js.map} +0 -0
- /package/dist/{chunk-G5OB4XZX.js.map → chunk-VANZKHTN.js.map} +0 -0
- /package/dist/{chunk-7DRSWPUV.js.map → chunk-VUP47UJI.js.map} +0 -0
- /package/dist/{chunk-65NQFK7D.js.map → chunk-WBM5NR4E.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-63JMI45N.js.map → chunk-XBRGJJK7.js.map} +0 -0
- /package/dist/{chunk-WCWIV2JH.js.map → chunk-XH4IQVTN.js.map} +0 -0
- /package/dist/{chunk-77E7LLMV.js.map → chunk-XZUCNVGE.js.map} +0 -0
- /package/dist/{chunk-LJQGQUNS.js.map → chunk-YFQTDE7N.js.map} +0 -0
- /package/dist/{chunk-5OOTHWGJ.js.map → chunk-YXGU3MDQ.js.map} +0 -0
- /package/dist/{chunk-SRLQROQJ.js.map → chunk-Z6CJLYXT.js.map} +0 -0
- /package/dist/{chunk-Z4UPRZR6.js.map → chunk-ZSYE2QVJ.js.map} +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location context subsystem — shared types (issue #2044).
|
|
3
|
+
*
|
|
4
|
+
* A host-agnostic foundation: the provider contract, the observation/day
|
|
5
|
+
* shapes, and health-check results. No HTTP client lives here — providers are
|
|
6
|
+
* registered from host adapters (a future provider package is one such
|
|
7
|
+
* adapter), keeping `@remnic/core` free of host SDKs and network specifics.
|
|
8
|
+
*
|
|
9
|
+
* All timestamps are UTC ISO-8601; day bucketing is half-open [start, end).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** A named place the user was observed at. */
|
|
13
|
+
export interface LocationPlace {
|
|
14
|
+
/** Provider-stable place identifier. */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Human-readable label, already redacted by the provider. */
|
|
17
|
+
label: string;
|
|
18
|
+
kind?: "home" | "work" | "poi" | "transit" | "other";
|
|
19
|
+
/** Present only when coordinate retention is enabled. */
|
|
20
|
+
latitude?: number;
|
|
21
|
+
longitude?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** One place observation at a single instant, from a single provider. */
|
|
25
|
+
export interface LocationObservation {
|
|
26
|
+
/** UTC ISO-8601 observation instant. */
|
|
27
|
+
observedAtUtc: string;
|
|
28
|
+
place: LocationPlace;
|
|
29
|
+
/** Provider confidence in [0,1], when reported. */
|
|
30
|
+
confidence?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** One page of observations from a provider fetch. */
|
|
34
|
+
export interface LocationObservationPage {
|
|
35
|
+
observations: LocationObservation[];
|
|
36
|
+
nextCursor: string | null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Result of a provider auth/health probe. */
|
|
40
|
+
export interface LocationProviderCheck {
|
|
41
|
+
ok: boolean;
|
|
42
|
+
detail?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Provider contract for a location source. Implemented by host adapters and
|
|
47
|
+
* registered in `registry.ts`; core never statically imports a provider
|
|
48
|
+
* package, so à-la-carte installs stay partial (a source whose provider is
|
|
49
|
+
* not registered is skipped, not an error).
|
|
50
|
+
*/
|
|
51
|
+
export interface LocationProvider {
|
|
52
|
+
/** Stable provider id (registry key; matches a config source id). */
|
|
53
|
+
id: string;
|
|
54
|
+
displayName: string;
|
|
55
|
+
/** Probe connectivity/auth without mutating anything. */
|
|
56
|
+
verify(signal?: AbortSignal): Promise<LocationProviderCheck>;
|
|
57
|
+
/** Fetch every observation in the half-open [startUtc, endUtc) window. */
|
|
58
|
+
fetchObservations(opts: {
|
|
59
|
+
startUtc: string;
|
|
60
|
+
endUtc: string;
|
|
61
|
+
cursor?: string | null;
|
|
62
|
+
signal?: AbortSignal;
|
|
63
|
+
}): Promise<LocationObservationPage>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** One configured location source: a registered provider plus its toggle. */
|
|
67
|
+
export interface LocationSourceConfig {
|
|
68
|
+
/** Must match a registered provider id. */
|
|
69
|
+
id: string;
|
|
70
|
+
/** `false` short-circuits this source only. */
|
|
71
|
+
enabled: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Opt-in location synchronization settings. */
|
|
75
|
+
export interface LocationConfig {
|
|
76
|
+
/** Master gate: `false` short-circuits every location path. */
|
|
77
|
+
enabled: boolean;
|
|
78
|
+
/** IANA timezone used to bucket observations into local days. */
|
|
79
|
+
timezone: string;
|
|
80
|
+
/** Number of local days to synchronize per run; integer 1..90. */
|
|
81
|
+
syncDays: number;
|
|
82
|
+
/**
|
|
83
|
+
* When `false` (the default), place coordinates are dropped before any
|
|
84
|
+
* persistence, rendering, or error reporting — only place labels remain.
|
|
85
|
+
*/
|
|
86
|
+
retainCoordinates: boolean;
|
|
87
|
+
sources: LocationSourceConfig[];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** A time-resolved place visit derived from consecutive observations. */
|
|
91
|
+
export interface LocationSegment {
|
|
92
|
+
startUtc: string;
|
|
93
|
+
endUtc: string;
|
|
94
|
+
place: LocationPlace;
|
|
95
|
+
}
|
package/src/okf/cli.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { lintOkfDir } from "./lint.js";
|
|
2
|
+
import { runOkfConformanceSweep } from "./sweep.js";
|
|
3
|
+
|
|
4
|
+
export async function runOkfCliCommand(
|
|
5
|
+
argv: string[],
|
|
6
|
+
io: { stdout: NodeJS.WritableStream; stderr: NodeJS.WritableStream },
|
|
7
|
+
ctx: { memoryDir: string; conformanceEnabled: boolean; sweepEnabled: boolean },
|
|
8
|
+
): Promise<number> {
|
|
9
|
+
const [subcommand, ...rest] = argv;
|
|
10
|
+
if (subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
|
|
11
|
+
io.stdout.write(`usage: remnic okf <lint|sweep> [--json]
|
|
12
|
+
lint report OKF conformance findings (exit 1 when findings remain)
|
|
13
|
+
sweep backfill missing type values (requires okf.sweepEnabled)
|
|
14
|
+
`);
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
if (subcommand !== "lint" && subcommand !== "sweep") {
|
|
18
|
+
io.stderr.write("okf: expected lint or sweep\n");
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
for (const token of rest) {
|
|
22
|
+
if (token === "--json") continue;
|
|
23
|
+
io.stderr.write(`okf: unexpected argument '${token}' — usage: remnic okf <lint|sweep> [--json]\n`);
|
|
24
|
+
return 1;
|
|
25
|
+
}
|
|
26
|
+
const json = rest.includes("--json");
|
|
27
|
+
if (subcommand === "sweep") {
|
|
28
|
+
const result = runOkfConformanceSweep(ctx.memoryDir, ctx);
|
|
29
|
+
if (json) io.stdout.write(`${JSON.stringify(result)}\n`);
|
|
30
|
+
else io.stdout.write(`okf sweep: scanned ${result.scanned}, wrote ${result.written}\n`);
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
const result = lintOkfDir(ctx.memoryDir);
|
|
34
|
+
if (json) io.stdout.write(`${JSON.stringify(result)}\n`);
|
|
35
|
+
else {
|
|
36
|
+
io.stdout.write(`okf lint: scanned ${result.scanned}, findings ${result.findings.length}\n`);
|
|
37
|
+
for (const finding of result.findings) {
|
|
38
|
+
io.stdout.write(` ${finding.file}: ${finding.message}\n`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result.ok ? 0 : 1;
|
|
42
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OKF conformance config (issue #1946). Parsed off the raw `okf` config
|
|
3
|
+
* block; mirrors the meetings/wearables parse-module seam so config.ts
|
|
4
|
+
* stays a thin caller.
|
|
5
|
+
*/
|
|
6
|
+
import { coerceBooleanLike } from "../connectors/coerce.js";
|
|
7
|
+
|
|
8
|
+
export interface OkfConfig {
|
|
9
|
+
/** Emit inert OKF `type` metadata on writes and gate the sweep (default true). */
|
|
10
|
+
conformanceEnabled: boolean;
|
|
11
|
+
/** Opt-in governance sweep that backfills `type` on legacy files (default false). */
|
|
12
|
+
sweepEnabled: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const DEFAULT_OKF_CONFIG: OkfConfig = Object.freeze({
|
|
16
|
+
conformanceEnabled: true,
|
|
17
|
+
sweepEnabled: false,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export function parseOkfConfig(raw: unknown): OkfConfig {
|
|
21
|
+
if (raw === undefined || raw === null) return { ...DEFAULT_OKF_CONFIG };
|
|
22
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`okf must be an object (got ${JSON.stringify(raw)}). Use okf: { conformanceEnabled: false } to opt out; omit the key for defaults.`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const record = raw as Record<string, unknown>;
|
|
28
|
+
const conformance = coerceBooleanLike(record.conformanceEnabled, "okf.conformanceEnabled");
|
|
29
|
+
const sweep = coerceBooleanLike(record.sweepEnabled, "okf.sweepEnabled");
|
|
30
|
+
return {
|
|
31
|
+
conformanceEnabled: conformance ?? DEFAULT_OKF_CONFIG.conformanceEnabled,
|
|
32
|
+
sweepEnabled: sweep ?? DEFAULT_OKF_CONFIG.sweepEnabled,
|
|
33
|
+
};
|
|
34
|
+
}
|
package/src/okf/lint.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import { MAGIC_BYTES } from "../secure-store/secure-fs.js";
|
|
5
|
+
import { OKF_RESERVED_BASENAMES } from "./type-mapping.js";
|
|
6
|
+
|
|
7
|
+
export interface OkfLintFinding {
|
|
8
|
+
file: string;
|
|
9
|
+
code: "missing_frontmatter" | "missing_type" | "empty_type" | "reserved_basename" | "skipped_encrypted";
|
|
10
|
+
message: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface OkfLintResult {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
scanned: number;
|
|
16
|
+
findings: OkfLintFinding[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isEncryptedBlob(raw: string): boolean {
|
|
20
|
+
// secure-store writes a binary envelope starting with MAGIC_BYTES at offset
|
|
21
|
+
// 0 — match that fixed position, never a substring anywhere in the file.
|
|
22
|
+
return raw.startsWith(MAGIC_BYTES.toString("ascii"));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function hasFrontmatter(raw: string): boolean {
|
|
26
|
+
return raw.startsWith("---\n") || raw.startsWith("---\r\n");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function readType(raw: string): string | undefined {
|
|
30
|
+
const close = raw.indexOf("\n---", 4);
|
|
31
|
+
if (close === -1) return undefined;
|
|
32
|
+
const block = raw.slice(4, close);
|
|
33
|
+
const match = /^type:[ \t]*(.*)$/m.exec(block);
|
|
34
|
+
if (!match) return undefined;
|
|
35
|
+
const value = match[1]!.trim().replace(/^["']|["']$/g, "");
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function walkMarkdown(root: string, out: string[]): void {
|
|
40
|
+
let entries: fs.Dirent[];
|
|
41
|
+
try {
|
|
42
|
+
entries = fs.readdirSync(root, { withFileTypes: true });
|
|
43
|
+
} catch {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
47
|
+
if (entry.name === "state" || entry.name === ".git") continue;
|
|
48
|
+
const full = path.join(root, entry.name);
|
|
49
|
+
let stat: fs.Stats;
|
|
50
|
+
try {
|
|
51
|
+
stat = fs.lstatSync(full);
|
|
52
|
+
} catch {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (stat.isSymbolicLink()) continue;
|
|
56
|
+
if (stat.isDirectory()) {
|
|
57
|
+
walkMarkdown(full, out);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (stat.isFile() && entry.name.endsWith(".md")) out.push(full);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function lintOkfDir(memoryDir: string): OkfLintResult {
|
|
65
|
+
const files: string[] = [];
|
|
66
|
+
walkMarkdown(memoryDir, files);
|
|
67
|
+
const findings: OkfLintFinding[] = [];
|
|
68
|
+
for (const file of files) {
|
|
69
|
+
const rel = path.relative(memoryDir, file);
|
|
70
|
+
const base = path.basename(file);
|
|
71
|
+
if (OKF_RESERVED_BASENAMES[base] === true) {
|
|
72
|
+
findings.push({
|
|
73
|
+
file: rel,
|
|
74
|
+
code: "reserved_basename",
|
|
75
|
+
message: `${base} is reserved by OKF §6/§7`,
|
|
76
|
+
});
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
let raw: string;
|
|
80
|
+
try {
|
|
81
|
+
raw = fs.readFileSync(file, "utf8");
|
|
82
|
+
} catch {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (isEncryptedBlob(raw)) {
|
|
86
|
+
findings.push({
|
|
87
|
+
file: rel,
|
|
88
|
+
code: "skipped_encrypted",
|
|
89
|
+
message: "skipped (encrypted)",
|
|
90
|
+
});
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (!hasFrontmatter(raw)) {
|
|
94
|
+
findings.push({
|
|
95
|
+
file: rel,
|
|
96
|
+
code: "missing_frontmatter",
|
|
97
|
+
message: "missing YAML frontmatter",
|
|
98
|
+
});
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const type = readType(raw);
|
|
102
|
+
if (type === undefined) {
|
|
103
|
+
findings.push({ file: rel, code: "missing_type", message: "missing type" });
|
|
104
|
+
} else if (type.length === 0) {
|
|
105
|
+
findings.push({ file: rel, code: "empty_type", message: "empty type" });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const actionable = findings.filter((f) => f.code !== "skipped_encrypted");
|
|
109
|
+
return { ok: actionable.length === 0, scanned: files.length, findings };
|
|
110
|
+
}
|
package/src/okf/sweep.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import { lintOkfDir } from "./lint.js";
|
|
5
|
+
import { okfTypeForCategory } from "./type-mapping.js";
|
|
6
|
+
|
|
7
|
+
export interface OkfSweepResult {
|
|
8
|
+
scanned: number;
|
|
9
|
+
written: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function insertType(raw: string, type: string): string | null {
|
|
13
|
+
const crlf = raw.startsWith("---\r\n");
|
|
14
|
+
if (!crlf && !raw.startsWith("---\n")) return null;
|
|
15
|
+
const lines = raw.split("\n");
|
|
16
|
+
let close = -1;
|
|
17
|
+
for (let index = 1; index < lines.length; index += 1) {
|
|
18
|
+
const line = lines[index]!;
|
|
19
|
+
if (line === "---" || line === "---\r" || line === "...") {
|
|
20
|
+
close = index;
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (close === -1) return null;
|
|
25
|
+
const block = lines.slice(1, close);
|
|
26
|
+
const categoryLine = block.find((line) => line.startsWith("category:"));
|
|
27
|
+
const category = categoryLine
|
|
28
|
+
? categoryLine.slice("category:".length).trim().replace(/^["']|["']$/g, "")
|
|
29
|
+
: "fact";
|
|
30
|
+
const resolved = type || okfTypeForCategory(category);
|
|
31
|
+
const typeIndex = block.findIndex((line) => line.startsWith("type:"));
|
|
32
|
+
if (typeIndex === -1) {
|
|
33
|
+
block.push(`type: ${resolved}${crlf ? "\r" : ""}`);
|
|
34
|
+
} else {
|
|
35
|
+
const current = block[typeIndex]!;
|
|
36
|
+
const bare = current.endsWith("\r") ? current.slice(0, -1) : current;
|
|
37
|
+
const value = bare.slice("type:".length).trim().replace(/^["']|["']$/g, "");
|
|
38
|
+
if (value !== "") return null;
|
|
39
|
+
block[typeIndex] = `type: ${resolved}${current.endsWith("\r") ? "\r" : ""}`;
|
|
40
|
+
}
|
|
41
|
+
return [lines[0], ...block, ...lines.slice(close)].join("\n");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function runOkfConformanceSweep(
|
|
45
|
+
memoryDir: string,
|
|
46
|
+
options: { sweepEnabled: boolean; conformanceEnabled: boolean },
|
|
47
|
+
): OkfSweepResult {
|
|
48
|
+
if (!options.sweepEnabled || !options.conformanceEnabled) {
|
|
49
|
+
return { scanned: 0, written: 0 };
|
|
50
|
+
}
|
|
51
|
+
const lint = lintOkfDir(memoryDir);
|
|
52
|
+
let written = 0;
|
|
53
|
+
for (const finding of lint.findings) {
|
|
54
|
+
if (finding.code !== "missing_type" && finding.code !== "empty_type") continue;
|
|
55
|
+
const file = path.join(memoryDir, finding.file);
|
|
56
|
+
const raw = fs.readFileSync(file, "utf8");
|
|
57
|
+
const next = insertType(raw, "");
|
|
58
|
+
if (next === null || next === raw) continue;
|
|
59
|
+
fs.writeFileSync(file, next);
|
|
60
|
+
written += 1;
|
|
61
|
+
}
|
|
62
|
+
return { scanned: lint.scanned, written };
|
|
63
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtemp, mkdir, writeFile, readFile, rm } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
|
|
7
|
+
import { runOkfCliCommand } from "./cli.js";
|
|
8
|
+
import { lintOkfDir } from "./lint.js";
|
|
9
|
+
import { runOkfConformanceSweep } from "./sweep.js";
|
|
10
|
+
import {
|
|
11
|
+
assertNotOkfReservedBasename,
|
|
12
|
+
okfTypeForCategory,
|
|
13
|
+
okfTypeForEntityKind,
|
|
14
|
+
okfTypeForMemory,
|
|
15
|
+
} from "./type-mapping.js";
|
|
16
|
+
import { parseEntityFile, serializeEntityFile } from "../storage.js";
|
|
17
|
+
import { parseOkfConfig } from "./config.js";
|
|
18
|
+
import { stripOkfProfileFrontmatter, withOkfProfileFrontmatter } from "../storage/profile-header.js";
|
|
19
|
+
|
|
20
|
+
test("okfTypeForCategory maps known categories and falls back", () => {
|
|
21
|
+
assert.equal(okfTypeForCategory("fact"), "Memory Fact");
|
|
22
|
+
assert.equal(okfTypeForCategory("decision"), "Decision");
|
|
23
|
+
assert.equal(okfTypeForCategory("unknown-future"), "Memory");
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("okfTypeForMemory prefers Artifact when artifactType is set", () => {
|
|
27
|
+
assert.equal(okfTypeForMemory({ category: "fact" }), "Memory Fact");
|
|
28
|
+
assert.equal(okfTypeForMemory({ category: "fact", artifactType: "image" }), "Artifact");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("okfTypeForEntityKind maps kinds and defaults to Entity", () => {
|
|
32
|
+
assert.equal(okfTypeForEntityKind("person"), "Person");
|
|
33
|
+
assert.equal(okfTypeForEntityKind("PROJECT"), "Project");
|
|
34
|
+
assert.equal(okfTypeForEntityKind(undefined), "Entity");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("reserved basenames are rejected", () => {
|
|
38
|
+
assert.throws(() => assertNotOkfReservedBasename("/mem/index.md"), /reserved basename/);
|
|
39
|
+
assert.throws(() => assertNotOkfReservedBasename("/mem/log.md"), /reserved basename/);
|
|
40
|
+
assert.doesNotThrow(() => assertNotOkfReservedBasename("/mem/facts/fact-1.md"));
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("type never overrides category — mapping is presentation only", () => {
|
|
44
|
+
assert.equal(okfTypeForCategory("fact"), "Memory Fact");
|
|
45
|
+
assert.notEqual(okfTypeForCategory("fact"), "fact");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("parseOkfConfig treats false as a real disable", () => {
|
|
49
|
+
assert.deepEqual(parseOkfConfig({ conformanceEnabled: false, sweepEnabled: "false" }), {
|
|
50
|
+
conformanceEnabled: false,
|
|
51
|
+
sweepEnabled: false,
|
|
52
|
+
});
|
|
53
|
+
assert.throws(() => parseOkfConfig("nope"), /okf must be an object/);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("profile OKF frontmatter strips back to the original injection bytes", () => {
|
|
57
|
+
const original = "# User\n\nPrefers short answers.\n";
|
|
58
|
+
const stamped = withOkfProfileFrontmatter(original, "2026-08-18T00:00:00.000Z", true);
|
|
59
|
+
assert.match(stamped, /^---\n/);
|
|
60
|
+
assert.match(stamped, /type: Profile/);
|
|
61
|
+
assert.equal(stripOkfProfileFrontmatter(stamped), original);
|
|
62
|
+
assert.equal(withOkfProfileFrontmatter(original, "2026-08-18T00:00:00.000Z", false), original);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("lintOkfDir reports missing type and skips only real encrypted envelopes", async () => {
|
|
66
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-okf-lint-"));
|
|
67
|
+
try {
|
|
68
|
+
await mkdir(path.join(dir, "facts", "2026-08-18"), { recursive: true });
|
|
69
|
+
await writeFile(
|
|
70
|
+
path.join(dir, "facts", "2026-08-18", "fact-ok.md"),
|
|
71
|
+
"---\nid: fact-ok\ncategory: fact\ntype: Memory Fact\n---\n\nhello\n",
|
|
72
|
+
);
|
|
73
|
+
await writeFile(
|
|
74
|
+
path.join(dir, "facts", "2026-08-18", "fact-bare.md"),
|
|
75
|
+
"---\nid: fact-bare\ncategory: fact\n---\n\nno type\n",
|
|
76
|
+
);
|
|
77
|
+
// Binary secure-store envelope: starts with the REMNIC-ENC magic header.
|
|
78
|
+
await writeFile(path.join(dir, "secret.md"), "REMNIC-ENC\x00\x01cipher-bytes");
|
|
79
|
+
// Plaintext that merely mentions an encryption marker is NOT skipped.
|
|
80
|
+
await writeFile(
|
|
81
|
+
path.join(dir, "mentions-enc.md"),
|
|
82
|
+
"---\nid: mentions-enc\ncategory: fact\n---\n\ndiscusses enc:v1 in prose\n",
|
|
83
|
+
);
|
|
84
|
+
const result = lintOkfDir(dir);
|
|
85
|
+
assert.equal(result.scanned, 4);
|
|
86
|
+
assert.equal(result.ok, false);
|
|
87
|
+
assert.ok(result.findings.some((f) => f.code === "missing_type"));
|
|
88
|
+
const encrypted = result.findings.filter((f) => f.code === "skipped_encrypted");
|
|
89
|
+
assert.equal(encrypted.length, 1);
|
|
90
|
+
assert.equal(encrypted[0]!.file, "secret.md");
|
|
91
|
+
assert.ok(result.findings.some((f) => f.file === "mentions-enc.md" && f.code === "missing_type"));
|
|
92
|
+
} finally {
|
|
93
|
+
await rm(dir, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("sweep adds type without rewriting files that already have it", async () => {
|
|
98
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-okf-sweep-"));
|
|
99
|
+
try {
|
|
100
|
+
const file = path.join(dir, "fact-bare.md");
|
|
101
|
+
await writeFile(file, "---\nid: fact-bare\ncategory: fact\nupdated: 2026-01-01T00:00:00.000Z\n---\n\nno type\n");
|
|
102
|
+
assert.equal(runOkfConformanceSweep(dir, { sweepEnabled: false, conformanceEnabled: true }).written, 0);
|
|
103
|
+
const first = runOkfConformanceSweep(dir, { sweepEnabled: true, conformanceEnabled: true });
|
|
104
|
+
assert.equal(first.written, 1);
|
|
105
|
+
const raw = await readFile(file, "utf8");
|
|
106
|
+
assert.match(raw, /type: Memory Fact/);
|
|
107
|
+
assert.match(raw, /updated: 2026-01-01T00:00:00.000Z/);
|
|
108
|
+
assert.equal(runOkfConformanceSweep(dir, { sweepEnabled: true, conformanceEnabled: true }).written, 0);
|
|
109
|
+
} finally {
|
|
110
|
+
await rm(dir, { recursive: true, force: true });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("sweep replaces an empty type in place and stays idempotent", async () => {
|
|
115
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-okf-sweep-empty-"));
|
|
116
|
+
try {
|
|
117
|
+
const file = path.join(dir, "fact-empty.md");
|
|
118
|
+
await writeFile(file, "---\nid: fact-empty\ncategory: decision\ntype:\nupdated: 2026-01-01T00:00:00.000Z\n---\n\nempty type\n");
|
|
119
|
+
assert.equal(runOkfConformanceSweep(dir, { sweepEnabled: true, conformanceEnabled: true }).written, 1);
|
|
120
|
+
const raw = await readFile(file, "utf8");
|
|
121
|
+
const typeLines = raw.split("\n").filter((line) => line.startsWith("type:"));
|
|
122
|
+
assert.equal(typeLines.length, 1, "no duplicate type key after sweep");
|
|
123
|
+
assert.equal(typeLines[0], "type: Decision");
|
|
124
|
+
assert.match(raw, /updated: 2026-01-01T00:00:00.000Z/);
|
|
125
|
+
assert.equal(runOkfConformanceSweep(dir, { sweepEnabled: true, conformanceEnabled: true }).written, 0);
|
|
126
|
+
} finally {
|
|
127
|
+
await rm(dir, { recursive: true, force: true });
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("sweep handles CRLF frontmatter the same as LF", async () => {
|
|
132
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-okf-sweep-crlf-"));
|
|
133
|
+
try {
|
|
134
|
+
const file = path.join(dir, "fact-crlf.md");
|
|
135
|
+
await writeFile(
|
|
136
|
+
file,
|
|
137
|
+
"---\r\nid: fact-crlf\r\ncategory: fact\r\n---\r\n\r\ncrlf body\r\n",
|
|
138
|
+
);
|
|
139
|
+
assert.equal(runOkfConformanceSweep(dir, { sweepEnabled: true, conformanceEnabled: true }).written, 1);
|
|
140
|
+
const raw = await readFile(file, "utf8");
|
|
141
|
+
const typeLine = raw.split("\n").find((line) => line.startsWith("type:"));
|
|
142
|
+
assert.equal(typeLine, "type: Memory Fact\r");
|
|
143
|
+
assert.equal(runOkfConformanceSweep(dir, { sweepEnabled: true, conformanceEnabled: true }).written, 0);
|
|
144
|
+
} finally {
|
|
145
|
+
await rm(dir, { recursive: true, force: true });
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
test("profile OKF frontmatter strip tolerates CRLF-rewritten files", () => {
|
|
149
|
+
// A CRLF-rewriting editor converts the whole stamped file, OKF block included.
|
|
150
|
+
const crlfStamped =
|
|
151
|
+
"---\r\ntype: Profile\r\ntitle: User Profile\r\ntimestamp: 2026-08-18T00:00:00.000Z\r\n---\r\n# User\r\n\r\nPrefers short answers.\r\n";
|
|
152
|
+
assert.equal(stripOkfProfileFrontmatter(crlfStamped), "# User\r\n\r\nPrefers short answers.\r\n");
|
|
153
|
+
// Hand-written CRLF frontmatter without the marker round-trips untouched.
|
|
154
|
+
const handWritten = "---\r\ntitle: mine\r\n---\r\n\r\nbody\r\n";
|
|
155
|
+
assert.equal(stripOkfProfileFrontmatter(handWritten), handWritten);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test("runOkfCliCommand handles help and rejects unexpected tokens", async () => {
|
|
159
|
+
const chunks: string[] = [];
|
|
160
|
+
const stdout = { write: (s: string) => void chunks.push(s) } as unknown as NodeJS.WritableStream;
|
|
161
|
+
for (const argv of [["--help"], ["-h"], ["help"]]) {
|
|
162
|
+
const stderr = { write: () => {} } as unknown as NodeJS.WritableStream;
|
|
163
|
+
const code = await runOkfCliCommand(argv, { stdout, stderr }, {
|
|
164
|
+
memoryDir: "/tmp",
|
|
165
|
+
conformanceEnabled: true,
|
|
166
|
+
sweepEnabled: false,
|
|
167
|
+
});
|
|
168
|
+
assert.equal(code, 0);
|
|
169
|
+
assert.match(chunks.join(""), /usage: remnic okf/);
|
|
170
|
+
}
|
|
171
|
+
const errChunks: string[] = [];
|
|
172
|
+
const stderr = { write: (s: string) => void errChunks.push(s) } as unknown as NodeJS.WritableStream;
|
|
173
|
+
for (const token of ["--json=1", "--unknown", "stray"]) {
|
|
174
|
+
errChunks.length = 0;
|
|
175
|
+
const code = await runOkfCliCommand(["lint", token], { stdout, stderr }, {
|
|
176
|
+
memoryDir: "/tmp",
|
|
177
|
+
conformanceEnabled: true,
|
|
178
|
+
sweepEnabled: false,
|
|
179
|
+
});
|
|
180
|
+
assert.equal(code, 1);
|
|
181
|
+
assert.match(errChunks.join(""), new RegExp(`unexpected argument '${token}'`));
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("serializeEntityFile okfType gate omits type when off, emits one when on", () => {
|
|
186
|
+
const raw = [
|
|
187
|
+
"---",
|
|
188
|
+
"created: 2026-01-01T00:00:00.000Z",
|
|
189
|
+
"updated: 2026-01-01T00:00:00.000Z",
|
|
190
|
+
"type: Entity",
|
|
191
|
+
"---",
|
|
192
|
+
"",
|
|
193
|
+
"# Jane",
|
|
194
|
+
"",
|
|
195
|
+
"**Type:** person",
|
|
196
|
+
"**Updated:** 2026-01-01T00:00:00.000Z",
|
|
197
|
+
"",
|
|
198
|
+
].join("\n");
|
|
199
|
+
const entity = parseEntityFile(raw);
|
|
200
|
+
const off = serializeEntityFile(entity, undefined, false);
|
|
201
|
+
const on = serializeEntityFile(entity, undefined, true);
|
|
202
|
+
// Gate off: no type metadata is emitted (matches the questions-path gate).
|
|
203
|
+
assert.doesNotMatch(off, /^type:/m);
|
|
204
|
+
// Gate on: exactly one type, recomputed from the entity kind.
|
|
205
|
+
assert.equal(on.split("\n").filter((line) => line.startsWith("type:")).length, 1);
|
|
206
|
+
assert.match(on, /^type: Person$/m);
|
|
207
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OKF v0.1 `type` mapping (issue #1946) — the single source of truth for
|
|
3
|
+
* the inert `type` metadata emitted alongside Remnic's canonical fields.
|
|
4
|
+
*
|
|
5
|
+
* `category` remains the canonical internal field; `type` is
|
|
6
|
+
* presentation/interop metadata for OKF consumers and NEVER overrides
|
|
7
|
+
* `category` on parse (the parser reads `type` into its own field only).
|
|
8
|
+
*/
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
|
|
11
|
+
/** OKF `type` values derived from Remnic memory categories. */
|
|
12
|
+
export const OKF_TYPE_BY_CATEGORY: Readonly<Record<string, string>> = Object.freeze({
|
|
13
|
+
fact: "Memory Fact",
|
|
14
|
+
decision: "Decision",
|
|
15
|
+
preference: "Preference",
|
|
16
|
+
commitment: "Commitment",
|
|
17
|
+
relationship: "Relationship",
|
|
18
|
+
principle: "Principle",
|
|
19
|
+
moment: "Moment",
|
|
20
|
+
skill: "Skill",
|
|
21
|
+
correction: "Correction",
|
|
22
|
+
rule: "Rule",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/** Fallback for categories not listed above (unknown/future categories). */
|
|
26
|
+
export const OKF_TYPE_FALLBACK = "Memory";
|
|
27
|
+
|
|
28
|
+
/** Stable domain seam over the category table (single mapping source, AGENTS.md pattern 9). */
|
|
29
|
+
export function okfTypeForCategory(category: string): string {
|
|
30
|
+
return OKF_TYPE_BY_CATEGORY[category] ?? OKF_TYPE_FALLBACK;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Artifact memories report `Artifact` regardless of their storage category. */
|
|
34
|
+
export function okfTypeForMemory(fm: { category: string; artifactType?: string }): string {
|
|
35
|
+
return fm.artifactType ? "Artifact" : okfTypeForCategory(fm.category);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** OKF types for entity files, derived from the entity kind. */
|
|
39
|
+
export const OKF_TYPE_BY_ENTITY_KIND: Readonly<Record<string, string>> = Object.freeze({
|
|
40
|
+
person: "Person",
|
|
41
|
+
company: "Company",
|
|
42
|
+
organization: "Organization",
|
|
43
|
+
project: "Project",
|
|
44
|
+
topic: "Topic",
|
|
45
|
+
technology: "Technology",
|
|
46
|
+
place: "Place",
|
|
47
|
+
event: "Event",
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
/** Stable domain seam over the entity-kind table (single mapping source). */
|
|
51
|
+
export function okfTypeForEntityKind(kind: string | undefined): string {
|
|
52
|
+
const normalized = kind?.trim().toLowerCase();
|
|
53
|
+
return (normalized !== undefined && OKF_TYPE_BY_ENTITY_KIND[normalized]) || "Entity";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Fixed OKF types for non-memory bundle files. */
|
|
57
|
+
export const OKF_PROFILE_TYPE = "Profile";
|
|
58
|
+
export const OKF_QUESTION_TYPE = "Question";
|
|
59
|
+
export const OKF_DECISION_RECORD_TYPE = "Decision Record";
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* OKF §6/§7 reserve `index.md` and `log.md` for bundle-level files with a
|
|
63
|
+
* different contract. Remnic never writes them (separate issue), and writes
|
|
64
|
+
* targeting those basenames are rejected outright so a stray ID can never
|
|
65
|
+
* shadow a reserved bundle file.
|
|
66
|
+
*/
|
|
67
|
+
export const OKF_RESERVED_BASENAMES: Readonly<Record<string, true>> = Object.freeze({
|
|
68
|
+
"index.md": true,
|
|
69
|
+
"log.md": true,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
export function assertNotOkfReservedBasename(filePath: string): void {
|
|
73
|
+
const basename = path.basename(filePath);
|
|
74
|
+
if (OKF_RESERVED_BASENAMES[basename] === true) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`OKF reserved basename '${basename}' is not a valid memory file target (${filePath}); OKF §6/§7 reserves it for bundle-level files.`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -6,6 +6,7 @@ import { ALL_CATEGORY_DIRS } from "../utils/category-dir.js";
|
|
|
6
6
|
import {
|
|
7
7
|
isActivityDigestPath,
|
|
8
8
|
isArtifactMemoryPath,
|
|
9
|
+
isLocationDayPath,
|
|
9
10
|
isMeetingRecordPath,
|
|
10
11
|
} from "./orchestrator-helpers.js";
|
|
11
12
|
|
|
@@ -133,6 +134,7 @@ export function isSearchExcludedPath(
|
|
|
133
134
|
if (
|
|
134
135
|
isArtifactMemoryPath(candidate) ||
|
|
135
136
|
isNamespacedActivityDigestPath(candidate, policy.memoryDir) ||
|
|
137
|
+
isNamespacedLocationDayPath(candidate, policy.memoryDir) ||
|
|
136
138
|
isMeetingRecordPath(candidate)
|
|
137
139
|
) {
|
|
138
140
|
return true;
|
|
@@ -160,6 +162,21 @@ function isNamespacedActivityDigestPath(candidate: string, memoryDir?: string):
|
|
|
160
162
|
return isActivityDigestPath(namespaced[2] ?? "", memoryDir);
|
|
161
163
|
}
|
|
162
164
|
|
|
165
|
+
/**
|
|
166
|
+
* The location day-file check, applied against the NAMESPACE root a hit came
|
|
167
|
+
* from — same rationale as `isNamespacedActivityDigestPath`: a namespaced
|
|
168
|
+
* search rewrites hits to absolute paths beneath `…/namespaces/<ns>/`, so the
|
|
169
|
+
* root-aware predicate is re-measured against the namespace's own root.
|
|
170
|
+
*/
|
|
171
|
+
function isNamespacedLocationDayPath(candidate: string, memoryDir?: string): boolean {
|
|
172
|
+
if (isLocationDayPath(candidate, memoryDir)) return true;
|
|
173
|
+
if (memoryDir === undefined || memoryDir.length === 0) return false;
|
|
174
|
+
const relative = path.relative(memoryDir, path.resolve(memoryDir, candidate));
|
|
175
|
+
const namespaced = /^namespaces[\\/]([^\\/]+)[\\/](.*)$/.exec(relative);
|
|
176
|
+
if (namespaced === null) return false;
|
|
177
|
+
return isLocationDayPath(namespaced[2] ?? "", memoryDir);
|
|
178
|
+
}
|
|
179
|
+
|
|
163
180
|
/** A path as given, plus its form with a leading COLLECTION segment removed. */
|
|
164
181
|
function collectionSpellings(
|
|
165
182
|
filePath: string,
|