@remnic/core 9.69.41 → 9.69.42
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 +14 -13
- package/dist/access-admin-ops-surface.js +28 -28
- package/dist/access-authorization-probe.d.ts +14 -13
- package/dist/access-authorization-probe.js +29 -29
- package/dist/access-boundary.d.ts +14 -13
- package/dist/access-boundary.js +28 -28
- package/dist/access-cli.js +72 -72
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +14 -13
- package/dist/access-extraction-force-flush.js +28 -28
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-briefing.d.ts +14 -13
- package/dist/access-http-briefing.js +29 -29
- package/dist/access-http-lcm-compaction.d.ts +14 -13
- package/dist/access-http-lifecycle-flush.d.ts +14 -13
- package/dist/access-http-offline-stream.d.ts +14 -13
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +30 -30
- package/dist/access-http.d.ts +15 -14
- package/dist/access-http.js +43 -43
- package/dist/access-identity-continuity-surface.d.ts +11 -11
- package/dist/access-identity-continuity-surface.js +28 -28
- package/dist/access-lcm-surface.d.ts +14 -13
- package/dist/access-lcm-surface.js +28 -28
- package/dist/access-mcp-shared-context-tools.d.ts +14 -13
- package/dist/access-mcp.d.ts +14 -13
- package/dist/access-mcp.js +35 -35
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-DWsMc9Dh.d.ts → access-namespace-preflight-ShnAJ9uL.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +28 -28
- package/dist/access-observe-transcript.d.ts +11 -11
- package/dist/access-observe-write-category.d.ts +17 -1
- package/dist/access-observe-write-category.js +19 -2
- package/dist/access-observe-write-surface.d.ts +14 -13
- package/dist/access-observe-write-surface.js +28 -28
- package/dist/access-offline-manifest.d.ts +11 -11
- package/dist/access-offline-manifest.js +6 -6
- package/dist/access-operations-batch.js +29 -29
- package/dist/access-operations.d.ts +14 -13
- package/dist/access-operations.js +34 -34
- package/dist/access-recall-concurrency.d.ts +14 -13
- package/dist/access-recall-concurrency.js +28 -28
- package/dist/access-recall-response.d.ts +14 -13
- package/dist/access-recall-response.js +28 -28
- package/dist/access-recall-surface.d.ts +14 -13
- package/dist/access-recall-surface.js +28 -28
- package/dist/access-schema.d.ts +117 -114
- package/dist/access-schema.js +1 -1
- package/dist/{access-service-Cisy5YDq.d.ts → access-service-DjG_e2cM.d.ts} +75 -74
- package/dist/access-service-helpers.d.ts +14 -13
- package/dist/access-service.d.ts +14 -13
- package/dist/access-service.js +28 -28
- package/dist/access-surface-catalog.d.ts +14 -13
- package/dist/access-surface-catalog.js +30 -30
- package/dist/access-wearables-meetings-surface.d.ts +4 -4
- 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 +6 -6
- package/dist/activity/digest.d.ts +1 -1
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-7PGUFY7U.js → auto-sync-QZD4RD6H.js} +9 -5
- package/dist/{auto-sync-7PGUFY7U.js.map → auto-sync-QZD4RD6H.js.map} +1 -1
- package/dist/background-generation.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 +11 -11
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +7 -7
- 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 +7 -7
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-wcX1QhtQ.d.ts → catalog-BhuXaQHx.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 +8 -8
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-XRS65T4O.js → chunk-2PDMIPMP.js} +6 -6
- package/dist/{chunk-MCMS4VUK.js → chunk-2UINSKQC.js} +4 -4
- package/dist/{chunk-XCPNH2MG.js → chunk-3KJTSCSX.js} +5 -5
- package/dist/{chunk-KJLLPG26.js → chunk-3RLWUW7G.js} +2 -2
- package/dist/{chunk-JMWUPUE6.js → chunk-46FVFU7S.js} +2 -2
- package/dist/{chunk-Z7NBT6AK.js → chunk-6EGIQEKC.js} +2 -2
- package/dist/{chunk-YFXAWGMR.js → chunk-7L54ARML.js} +2 -2
- package/dist/{chunk-C3G6MW4W.js → chunk-7PSRCGWT.js} +2 -2
- package/dist/{chunk-IYIPXAIJ.js → chunk-AAAFZW3U.js} +2 -2
- package/dist/{chunk-Z535ADTC.js → chunk-AAX22E4K.js} +2 -2
- package/dist/{chunk-I46BYY7U.js → chunk-ADARR5KF.js} +69 -51
- package/dist/{chunk-I46BYY7U.js.map → chunk-ADARR5KF.js.map} +1 -1
- package/dist/{chunk-W7UV2ZCA.js → chunk-AHHFBJX7.js} +2 -2
- package/dist/{chunk-KZJM7R4F.js → chunk-AOGICQMH.js} +6 -6
- package/dist/{chunk-PGGPRF6J.js → chunk-BIANISES.js} +2 -2
- package/dist/{chunk-3BLHPQHT.js → chunk-BPXJINHW.js} +5 -5
- package/dist/{chunk-2J3V5QEO.js → chunk-C3QXITIP.js} +4 -4
- package/dist/{chunk-I33QYUAF.js → chunk-CQ4BTPX6.js} +2 -2
- package/dist/{chunk-D6PY63OM.js → chunk-CTETTVDN.js} +2 -2
- package/dist/{chunk-P66QH6R6.js → chunk-DLPMOSNH.js} +2 -2
- package/dist/{chunk-E3I3NDUP.js → chunk-DMTSKY4W.js} +7 -7
- package/dist/{chunk-AFJHNHAM.js → chunk-E4FRR4MA.js} +2 -2
- package/dist/{chunk-46RII65S.js → chunk-ETE3SGAH.js} +2 -2
- package/dist/{chunk-K5D2XVNN.js → chunk-F2FJTOV6.js} +2 -2
- package/dist/{chunk-7ZLC4DTZ.js → chunk-F6PTJLEM.js} +1 -1
- package/dist/chunk-F6PTJLEM.js.map +1 -0
- package/dist/{chunk-54QPOE45.js → chunk-FSUFKIFS.js} +2 -2
- package/dist/{chunk-E4LMQTST.js → chunk-G3NTZZWT.js} +2 -2
- package/dist/{chunk-WFMQN7JE.js → chunk-GIM2AGFL.js} +3 -3
- package/dist/{chunk-RQQO3ORQ.js → chunk-GR76OKET.js} +13 -4
- package/dist/{chunk-RQQO3ORQ.js.map → chunk-GR76OKET.js.map} +1 -1
- package/dist/{chunk-WZIO3TW6.js → chunk-GWEZNCGA.js} +2 -2
- package/dist/{chunk-PQ42DJNG.js → chunk-H2N6SLTR.js} +2 -2
- package/dist/{chunk-V62YYBBY.js → chunk-HK44SV6K.js} +2 -2
- package/dist/{chunk-GMH5QPUU.js → chunk-HO2P3FAX.js} +12 -12
- package/dist/{chunk-ZX6NNFSY.js → chunk-HPMCKAET.js} +2 -2
- package/dist/{chunk-N6XTC56E.js → chunk-HSJU6JFT.js} +7 -9
- package/dist/chunk-HSJU6JFT.js.map +1 -0
- package/dist/{chunk-ICN37XHG.js → chunk-I65KB36L.js} +11 -11
- package/dist/{chunk-S4MJTIPG.js → chunk-IUTYNDFS.js} +47 -45
- package/dist/chunk-IUTYNDFS.js.map +1 -0
- package/dist/{chunk-ND7MAIJC.js → chunk-JC2OBYYD.js} +2 -2
- package/dist/{chunk-5EQT62HH.js → chunk-JMAP6L6Q.js} +2 -2
- package/dist/{chunk-A4OIJYCV.js → chunk-K27INAPR.js} +2 -2
- package/dist/{chunk-FGFC2EFR.js → chunk-KCKXOS4Y.js} +2 -2
- package/dist/{chunk-EMSYMYXO.js → chunk-KJQ4Y2PY.js} +8 -8
- package/dist/{chunk-NYWCFC3K.js → chunk-L732NBPR.js} +35 -35
- package/dist/{chunk-JSD7Q7LD.js → chunk-LCVYO3ON.js} +2 -2
- package/dist/{chunk-WBQ4ONQJ.js → chunk-LWF6GOII.js} +2 -2
- package/dist/{chunk-V2EXYQEQ.js → chunk-N7B6V7SG.js} +7 -7
- package/dist/{chunk-UZGHKD3T.js → chunk-OCWFKD5Q.js} +2 -2
- package/dist/{chunk-AKABVXFS.js → chunk-OP722LOG.js} +1 -1
- package/dist/{chunk-I3H5LFOI.js → chunk-QNJQCLI6.js} +4 -4
- package/dist/{chunk-6MQMYXSQ.js → chunk-R45VFSEV.js} +2 -2
- package/dist/{chunk-XVDZFTN5.js → chunk-RFIJH2OE.js} +5 -5
- package/dist/{chunk-BTPCP535.js → chunk-RJ7Z7YXK.js} +5 -5
- package/dist/{chunk-ZZEIL3MI.js → chunk-RSSLDMFX.js} +2 -2
- package/dist/{chunk-ZZEIL3MI.js.map → chunk-RSSLDMFX.js.map} +1 -1
- package/dist/{chunk-V2TOGJPM.js → chunk-RTXHUVOD.js} +8 -7
- package/dist/chunk-RTXHUVOD.js.map +1 -0
- package/dist/{chunk-DIXZQTGY.js → chunk-RXYO6NA6.js} +2 -2
- package/dist/{chunk-TBXAY2SS.js → chunk-SGHGCFVV.js} +5 -5
- package/dist/{chunk-KLUC2GSG.js → chunk-U26LB4WA.js} +5 -5
- package/dist/{chunk-6P4REYKL.js → chunk-UDAUULK2.js} +28 -2
- package/dist/{chunk-6P4REYKL.js.map → chunk-UDAUULK2.js.map} +1 -1
- package/dist/{chunk-2HQPE2NM.js → chunk-VBK6SRNE.js} +2 -2
- package/dist/{chunk-H3TKENU4.js → chunk-WIKO4SCR.js} +5 -5
- package/dist/{chunk-563X6JJX.js → chunk-WNPRRBOE.js} +2 -2
- package/dist/{chunk-2ZG2LLZT.js → chunk-XJLTQTAO.js} +2 -2
- package/dist/{chunk-PFKIOYJH.js → chunk-ZFU6QNRN.js} +7 -7
- package/dist/{chunk-WPGA4RYI.js → chunk-ZGXHTV5Y.js} +2 -2
- package/dist/{chunk-DM5CU5J7.js → chunk-ZOGKZ2XT.js} +2 -1
- package/dist/chunk-ZOGKZ2XT.js.map +1 -0
- package/dist/{chunk-LE2KZ72G.js → chunk-ZYRAY5FL.js} +2 -2
- package/dist/{cli-CUlMlS2N.d.ts → cli-Cx9s_VRn.d.ts} +5 -5
- package/dist/cli.d.ts +16 -15
- package/dist/cli.js +58 -58
- package/dist/coding/export-okf-codegraph.d.ts +1 -1
- package/dist/coding/export-okf-codegraph.js +7 -7
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +7 -7
- 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 +6 -6
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +7 -7
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +8 -8
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +4 -4
- package/dist/contradiction/index.js +3 -3
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +10 -10
- 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 +10 -10
- package/dist/cross-lingual-recall.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/deep-recall-http-glue.d.ts +14 -13
- package/dist/deep-recall-http-glue.js +2 -2
- package/dist/deep-recall-mcp-tools.d.ts +14 -13
- package/dist/deep-recall-policy-llm.d.ts +2 -2
- package/dist/deep-recall-seeds.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-BDDjImQn.d.ts → dependency-propagation-delivery-C2QFQ97b.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 +7 -7
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/eval-trajectory-contracts.d.ts +1 -1
- package/dist/eval-trajectory-store.d.ts +1 -1
- package/dist/eval-trajectory.d.ts +1 -1
- package/dist/explicit-capture.d.ts +11 -11
- package/dist/explicit-capture.js +3 -3
- package/dist/external-wiki-access.d.ts +14 -13
- package/dist/external-wiki-access.js +29 -29
- 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 +14 -13
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +2 -2
- package/dist/extraction-judge-telemetry.d.ts +2 -2
- package/dist/extraction-judge-training.d.ts +2 -2
- package/dist/extraction-judge.d.ts +2 -2
- 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-span-config.d.ts +1 -1
- package/dist/extraction-span-materialize.d.ts +1 -1
- package/dist/extraction.d.ts +2 -2
- package/dist/extraction.js +15 -15
- package/dist/fallback-llm-codex-subscription.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{generic-recall-paths-CpDzNO_I.d.ts → generic-recall-paths-CeKQsQEn.d.ts} +1 -1
- package/dist/graph-append-error.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-jsonl.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/importers/test-utils.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/{index-CtmmCJoo.d.ts → index-Bau-Wl0H.d.ts} +3 -3
- package/dist/index.d.ts +702 -701
- package/dist/index.js +126 -126
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/{local-llm-DpXIvm6F.d.ts → local-llm-Bj-m01Ro.d.ts} +1 -1
- package/dist/local-llm-helpers.d.ts +2 -2
- package/dist/local-llm.d.ts +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/location/index.d.ts +6 -209
- package/dist/location/index.js +62 -56
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +7 -7
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -8
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +9 -9
- package/dist/{maintenance-CNgoLsoM.d.ts → maintenance-Ye-y-c7f.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +14 -13
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-controller.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-subject-cli.d.ts +14 -13
- package/dist/memory-subject.d.ts +14 -13
- 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 +8 -8
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +7 -7
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/offline-sync-impression-drain.js +5 -5
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +11 -11
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +21 -21
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +20 -20
- package/dist/{orchestrator-DT7ybIFz.d.ts → orchestrator-fFDDYUUV.d.ts} +12 -10
- package/dist/orchestrator.d.ts +11 -11
- package/dist/orchestrator.js +72 -72
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CgBEmHcz.d.ts → pipeline-D_j5n_Ih.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +2 -2
- package/dist/provenance.d.ts +1 -1
- package/dist/{public-http-C8P8fyiO.d.ts → public-http-CjiSqxUx.d.ts} +1 -1
- package/dist/{qmd-BkY8KpCh.d.ts → qmd-CnxVjKrv.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-memory-map.d.ts +1 -1
- package/dist/recall-navigate-access.d.ts +1 -1
- package/dist/recall-navigate-disclosure.d.ts +1 -1
- package/dist/recall-navigate.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state-view-admission.d.ts +2 -2
- package/dist/recall-state-view-admission.js +4 -4
- package/dist/recall-state-view-anchors.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-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- 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/resolution-LXFQQ4AE.js +3 -3
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +7 -7
- 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 +160 -160
- package/dist/{scope-profiles-BBPjZ9jb.d.ts → scope-profiles-BajH5zAT.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-BPFFVO84.d.ts → semantic-consolidation-Bu6d3O7R.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +8 -8
- package/dist/semantic-rule-promotion.js +7 -7
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +7 -7
- package/dist/{service-jKcr6Jvr.d.ts → service-ChFwWtLS.d.ts} +13 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +7 -7
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +14 -14
- package/dist/standup/build.js +8 -8
- package/dist/{storage-C-0Ah5OY.d.ts → storage-BDKQdsmB.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +6 -6
- package/dist/subject-config.d.ts +1 -1
- package/dist/subject-config.js +2 -2
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +17 -16
- package/dist/support-passport/index.js +31 -31
- package/dist/tagging-CwK6um2q.d.ts +240 -0
- 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/export-okf.d.ts +1 -1
- package/dist/transfer/export-okf.js +7 -7
- package/dist/transfer/types.d.ts +78 -78
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-cK5LydjL.d.ts → types-B65IoepH.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +7 -7
- package/dist/who-knows-cli.d.ts +14 -13
- package/dist/who-knows-cli.js +8 -8
- package/dist/who-knows.d.ts +14 -13
- package/dist/who-knows.js +7 -7
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-http.test.ts +1 -0
- package/src/access-mcp.ts +3 -6
- package/src/access-observe-write-category.ts +1 -0
- package/src/access-observe-write-surface.ts +3 -3
- package/src/access-operations-batch.ts +2 -2
- package/src/access-schema.ts +1 -0
- package/src/access-service.ts +4 -5
- package/src/location/phase5-wiring.test.ts +408 -0
- package/src/location/tagging.ts +58 -0
- package/src/orchestration/orchestrator-helpers.ts +2 -0
- package/src/orchestration/workspace-ops.ts +14 -0
- package/src/wearables/pipeline.ts +19 -0
- package/src/wearables/service.ts +8 -0
- package/dist/chunk-7ZLC4DTZ.js.map +0 -1
- package/dist/chunk-DM5CU5J7.js.map +0 -1
- package/dist/chunk-N6XTC56E.js.map +0 -1
- package/dist/chunk-S4MJTIPG.js.map +0 -1
- package/dist/chunk-V2TOGJPM.js.map +0 -1
- /package/dist/{chunk-XRS65T4O.js.map → chunk-2PDMIPMP.js.map} +0 -0
- /package/dist/{chunk-MCMS4VUK.js.map → chunk-2UINSKQC.js.map} +0 -0
- /package/dist/{chunk-XCPNH2MG.js.map → chunk-3KJTSCSX.js.map} +0 -0
- /package/dist/{chunk-KJLLPG26.js.map → chunk-3RLWUW7G.js.map} +0 -0
- /package/dist/{chunk-JMWUPUE6.js.map → chunk-46FVFU7S.js.map} +0 -0
- /package/dist/{chunk-Z7NBT6AK.js.map → chunk-6EGIQEKC.js.map} +0 -0
- /package/dist/{chunk-YFXAWGMR.js.map → chunk-7L54ARML.js.map} +0 -0
- /package/dist/{chunk-C3G6MW4W.js.map → chunk-7PSRCGWT.js.map} +0 -0
- /package/dist/{chunk-IYIPXAIJ.js.map → chunk-AAAFZW3U.js.map} +0 -0
- /package/dist/{chunk-Z535ADTC.js.map → chunk-AAX22E4K.js.map} +0 -0
- /package/dist/{chunk-W7UV2ZCA.js.map → chunk-AHHFBJX7.js.map} +0 -0
- /package/dist/{chunk-KZJM7R4F.js.map → chunk-AOGICQMH.js.map} +0 -0
- /package/dist/{chunk-PGGPRF6J.js.map → chunk-BIANISES.js.map} +0 -0
- /package/dist/{chunk-3BLHPQHT.js.map → chunk-BPXJINHW.js.map} +0 -0
- /package/dist/{chunk-2J3V5QEO.js.map → chunk-C3QXITIP.js.map} +0 -0
- /package/dist/{chunk-I33QYUAF.js.map → chunk-CQ4BTPX6.js.map} +0 -0
- /package/dist/{chunk-D6PY63OM.js.map → chunk-CTETTVDN.js.map} +0 -0
- /package/dist/{chunk-P66QH6R6.js.map → chunk-DLPMOSNH.js.map} +0 -0
- /package/dist/{chunk-E3I3NDUP.js.map → chunk-DMTSKY4W.js.map} +0 -0
- /package/dist/{chunk-AFJHNHAM.js.map → chunk-E4FRR4MA.js.map} +0 -0
- /package/dist/{chunk-46RII65S.js.map → chunk-ETE3SGAH.js.map} +0 -0
- /package/dist/{chunk-K5D2XVNN.js.map → chunk-F2FJTOV6.js.map} +0 -0
- /package/dist/{chunk-54QPOE45.js.map → chunk-FSUFKIFS.js.map} +0 -0
- /package/dist/{chunk-E4LMQTST.js.map → chunk-G3NTZZWT.js.map} +0 -0
- /package/dist/{chunk-WFMQN7JE.js.map → chunk-GIM2AGFL.js.map} +0 -0
- /package/dist/{chunk-WZIO3TW6.js.map → chunk-GWEZNCGA.js.map} +0 -0
- /package/dist/{chunk-PQ42DJNG.js.map → chunk-H2N6SLTR.js.map} +0 -0
- /package/dist/{chunk-V62YYBBY.js.map → chunk-HK44SV6K.js.map} +0 -0
- /package/dist/{chunk-GMH5QPUU.js.map → chunk-HO2P3FAX.js.map} +0 -0
- /package/dist/{chunk-ZX6NNFSY.js.map → chunk-HPMCKAET.js.map} +0 -0
- /package/dist/{chunk-ICN37XHG.js.map → chunk-I65KB36L.js.map} +0 -0
- /package/dist/{chunk-ND7MAIJC.js.map → chunk-JC2OBYYD.js.map} +0 -0
- /package/dist/{chunk-5EQT62HH.js.map → chunk-JMAP6L6Q.js.map} +0 -0
- /package/dist/{chunk-A4OIJYCV.js.map → chunk-K27INAPR.js.map} +0 -0
- /package/dist/{chunk-FGFC2EFR.js.map → chunk-KCKXOS4Y.js.map} +0 -0
- /package/dist/{chunk-EMSYMYXO.js.map → chunk-KJQ4Y2PY.js.map} +0 -0
- /package/dist/{chunk-NYWCFC3K.js.map → chunk-L732NBPR.js.map} +0 -0
- /package/dist/{chunk-JSD7Q7LD.js.map → chunk-LCVYO3ON.js.map} +0 -0
- /package/dist/{chunk-WBQ4ONQJ.js.map → chunk-LWF6GOII.js.map} +0 -0
- /package/dist/{chunk-V2EXYQEQ.js.map → chunk-N7B6V7SG.js.map} +0 -0
- /package/dist/{chunk-UZGHKD3T.js.map → chunk-OCWFKD5Q.js.map} +0 -0
- /package/dist/{chunk-AKABVXFS.js.map → chunk-OP722LOG.js.map} +0 -0
- /package/dist/{chunk-I3H5LFOI.js.map → chunk-QNJQCLI6.js.map} +0 -0
- /package/dist/{chunk-6MQMYXSQ.js.map → chunk-R45VFSEV.js.map} +0 -0
- /package/dist/{chunk-XVDZFTN5.js.map → chunk-RFIJH2OE.js.map} +0 -0
- /package/dist/{chunk-BTPCP535.js.map → chunk-RJ7Z7YXK.js.map} +0 -0
- /package/dist/{chunk-DIXZQTGY.js.map → chunk-RXYO6NA6.js.map} +0 -0
- /package/dist/{chunk-TBXAY2SS.js.map → chunk-SGHGCFVV.js.map} +0 -0
- /package/dist/{chunk-KLUC2GSG.js.map → chunk-U26LB4WA.js.map} +0 -0
- /package/dist/{chunk-2HQPE2NM.js.map → chunk-VBK6SRNE.js.map} +0 -0
- /package/dist/{chunk-H3TKENU4.js.map → chunk-WIKO4SCR.js.map} +0 -0
- /package/dist/{chunk-563X6JJX.js.map → chunk-WNPRRBOE.js.map} +0 -0
- /package/dist/{chunk-2ZG2LLZT.js.map → chunk-XJLTQTAO.js.map} +0 -0
- /package/dist/{chunk-PFKIOYJH.js.map → chunk-ZFU6QNRN.js.map} +0 -0
- /package/dist/{chunk-WPGA4RYI.js.map → chunk-ZGXHTV5Y.js.map} +0 -0
- /package/dist/{chunk-LE2KZ72G.js.map → chunk-ZYRAY5FL.js.map} +0 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase-5 wiring regression (issue #2925): the existing location subsystem
|
|
3
|
+
* feeding wearables, day summaries, and briefings — conservatively.
|
|
4
|
+
*
|
|
5
|
+
* Pins the contract the umbrella issue (#2043) requires:
|
|
6
|
+
* - wearable location fill is missing-only and never overwrites a
|
|
7
|
+
* source-provided value;
|
|
8
|
+
* - conflicting / below-threshold overlaps stay untagged;
|
|
9
|
+
* - absent, disabled, or unrequested location changes NOTHING (the
|
|
10
|
+
* stored transcript body and gathered day summary are byte-identical);
|
|
11
|
+
* - day summaries and briefings expose place names only behind the
|
|
12
|
+
* explicit includeLocation request flag plus both location gates;
|
|
13
|
+
* - labels only — coordinates never reach any phase-5 output.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import assert from "node:assert/strict";
|
|
17
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
18
|
+
import { tmpdir } from "node:os";
|
|
19
|
+
import * as path from "node:path";
|
|
20
|
+
import { test } from "node:test";
|
|
21
|
+
|
|
22
|
+
import { StorageManager } from "../storage.js";
|
|
23
|
+
import { WorkspaceOpsCoordinator, type WorkspaceOpsDeps } from "../orchestration/workspace-ops.js";
|
|
24
|
+
import type { PluginConfig } from "../types.js";
|
|
25
|
+
import type {
|
|
26
|
+
WearableConversation,
|
|
27
|
+
WearableSourceConnector,
|
|
28
|
+
WearableSourceSettings,
|
|
29
|
+
WearablesConfig,
|
|
30
|
+
} from "../wearables/types.js";
|
|
31
|
+
import { defaultWearableSourceSettings, defaultWearablesConfig } from "../wearables/config.js";
|
|
32
|
+
import { parseDayTranscript } from "../wearables/day-store.js";
|
|
33
|
+
import { syncWearableSource, type WearableSyncDeps } from "../wearables/pipeline.js";
|
|
34
|
+
import { parseLocationConfig } from "./config.js";
|
|
35
|
+
import { saveLocationSyncState } from "./store.js";
|
|
36
|
+
import type { LocationConfig, LocationSegment } from "./types.js";
|
|
37
|
+
import { briefingLocationSection } from "./tagging.js";
|
|
38
|
+
|
|
39
|
+
const NOW = new Date("2026-06-11T03:00:00.000Z");
|
|
40
|
+
|
|
41
|
+
function locationConfig(overrides: Record<string, unknown> = {}): LocationConfig {
|
|
42
|
+
return parseLocationConfig({
|
|
43
|
+
enabled: true,
|
|
44
|
+
timezone: "UTC",
|
|
45
|
+
sources: [{ id: "reitti" }],
|
|
46
|
+
tagging: { enabled: true },
|
|
47
|
+
...overrides,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function segment(
|
|
52
|
+
startUtc: string,
|
|
53
|
+
endUtc: string,
|
|
54
|
+
label: string,
|
|
55
|
+
kind: LocationSegment["place"]["kind"] = "poi",
|
|
56
|
+
): LocationSegment {
|
|
57
|
+
return {
|
|
58
|
+
startUtc,
|
|
59
|
+
endUtc,
|
|
60
|
+
place: {
|
|
61
|
+
id: `reitti:place:${label.toLowerCase().replace(/\s+/g, "-")}`,
|
|
62
|
+
label,
|
|
63
|
+
kind,
|
|
64
|
+
latitude: 60.1699,
|
|
65
|
+
longitude: 24.9384,
|
|
66
|
+
},
|
|
67
|
+
confidence: 0.9,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function seedLocationDays(memoryDir: string, days: Record<string, LocationSegment[]>) {
|
|
72
|
+
await saveLocationSyncState(memoryDir, {
|
|
73
|
+
version: 1,
|
|
74
|
+
sources: {
|
|
75
|
+
reitti: {
|
|
76
|
+
days: Object.fromEntries(
|
|
77
|
+
Object.entries(days).map(([date, segments]) => [
|
|
78
|
+
date,
|
|
79
|
+
{ observationCount: segments.length, segments },
|
|
80
|
+
]),
|
|
81
|
+
),
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function wearableSettings(): WearableSourceSettings {
|
|
87
|
+
return { ...defaultWearableSourceSettings(), enabled: true };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function wearablesConfig(timezone = "UTC"): WearablesConfig {
|
|
91
|
+
return {
|
|
92
|
+
...defaultWearablesConfig(),
|
|
93
|
+
enabled: true,
|
|
94
|
+
timezone,
|
|
95
|
+
digestEnabled: false,
|
|
96
|
+
offTheRecordEnabled: false,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function conversation(
|
|
101
|
+
id: string,
|
|
102
|
+
startIso: string,
|
|
103
|
+
endIso: string,
|
|
104
|
+
overrides: Partial<WearableConversation> = {},
|
|
105
|
+
): WearableConversation {
|
|
106
|
+
return {
|
|
107
|
+
id,
|
|
108
|
+
source: "testsource",
|
|
109
|
+
title: `Conversation ${id}`,
|
|
110
|
+
startIso,
|
|
111
|
+
endIso,
|
|
112
|
+
segments: [{ speakerKey: "user", speakerName: "user", isWearer: true, text: "Synthetic wearable text." }],
|
|
113
|
+
...overrides,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function fakeConnector(byDate: Record<string, WearableConversation[]>): WearableSourceConnector {
|
|
118
|
+
return {
|
|
119
|
+
id: "testsource",
|
|
120
|
+
displayName: "Test Source",
|
|
121
|
+
async verifyAuth() {
|
|
122
|
+
return { ok: true };
|
|
123
|
+
},
|
|
124
|
+
async fetchConversations(opts: { date: string }) {
|
|
125
|
+
return { conversations: byDate[opts.date] ?? [], nextCursor: null };
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function makeSyncDeps(
|
|
131
|
+
memoryDir: string,
|
|
132
|
+
now: Date,
|
|
133
|
+
locationConfigValue?: LocationConfig,
|
|
134
|
+
): { deps: WearableSyncDeps; written: Array<{ source: string; date: string; serialized: string }> } {
|
|
135
|
+
const written: Array<{ source: string; date: string; serialized: string }> = [];
|
|
136
|
+
const deps: WearableSyncDeps = {
|
|
137
|
+
memoryDir,
|
|
138
|
+
async readDayContentHash() {
|
|
139
|
+
return null;
|
|
140
|
+
},
|
|
141
|
+
writeDayTranscript(source, date, serialized) {
|
|
142
|
+
written.push({ source, date, serialized });
|
|
143
|
+
return Promise.resolve();
|
|
144
|
+
},
|
|
145
|
+
memoryGen: null,
|
|
146
|
+
now: () => now,
|
|
147
|
+
...(locationConfigValue !== undefined ? { locationConfig: locationConfigValue } : {}),
|
|
148
|
+
};
|
|
149
|
+
return { deps, written };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function bodyOf(serialized: string): string {
|
|
153
|
+
const parsed = parseDayTranscript(serialized);
|
|
154
|
+
assert.ok(parsed, "day transcript parses");
|
|
155
|
+
return parsed.body;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ── Wearable fill ───────────────────────────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
test("wearable sync fills only missing conversation locations from a dominant overlap", async () => {
|
|
161
|
+
const memoryDir = mkdtempSync(path.join(tmpdir(), "remnic-phase5-fill-"));
|
|
162
|
+
try {
|
|
163
|
+
await seedLocationDays(memoryDir, {
|
|
164
|
+
"2026-06-11": [segment("2026-06-11T14:30:00.000Z", "2026-06-11T16:00:00.000Z", "Coffee shop")],
|
|
165
|
+
});
|
|
166
|
+
const { deps, written } = makeSyncDeps(memoryDir, NOW, locationConfig());
|
|
167
|
+
const connector = fakeConnector({
|
|
168
|
+
"2026-06-11": [
|
|
169
|
+
conversation("c-missing", "2026-06-11T15:00:00.000Z", "2026-06-11T15:30:00.000Z"),
|
|
170
|
+
conversation("c-source", "2026-06-11T15:00:00.000Z", "2026-06-11T15:30:00.000Z", {
|
|
171
|
+
location: "Office rooftop",
|
|
172
|
+
}),
|
|
173
|
+
],
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
await syncWearableSource(connector, wearableSettings(), wearablesConfig(), { days: 1 }, deps);
|
|
177
|
+
|
|
178
|
+
assert.equal(written.length, 1, "day transcript written");
|
|
179
|
+
const body = bodyOf(written[0].serialized);
|
|
180
|
+
assert.ok(body.includes("*Location: Coffee shop*"), "missing location filled from the dominant match");
|
|
181
|
+
const sourceSection = body.slice(body.indexOf("Conversation c-source"));
|
|
182
|
+
assert.ok(sourceSection.includes("*Location: Office rooftop*"), "source-provided location kept");
|
|
183
|
+
assert.ok(!sourceSection.includes("Coffee shop"), "source-provided value not overwritten");
|
|
184
|
+
} finally {
|
|
185
|
+
rmSync(memoryDir, { recursive: true, force: true });
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test("conflicting and below-threshold overlaps leave wearable locations unfilled", async () => {
|
|
190
|
+
const memoryDir = mkdtempSync(path.join(tmpdir(), "remnic-phase5-threshold-"));
|
|
191
|
+
try {
|
|
192
|
+
await seedLocationDays(memoryDir, {
|
|
193
|
+
// Two equal-overlap places → ambiguous (conflict).
|
|
194
|
+
"2026-06-11": [
|
|
195
|
+
segment("2026-06-11T15:00:00.000Z", "2026-06-11T15:15:00.000Z", "Diner"),
|
|
196
|
+
segment("2026-06-11T15:15:00.000Z", "2026-06-11T15:30:00.000Z", "Gym"),
|
|
197
|
+
],
|
|
198
|
+
// A 2-minute overlap only → below the 300s floor.
|
|
199
|
+
"2026-06-12": [segment("2026-06-12T15:28:00.000Z", "2026-06-12T16:30:00.000Z", "Library")],
|
|
200
|
+
});
|
|
201
|
+
const { deps, written } = makeSyncDeps(memoryDir, new Date("2026-06-12T03:00:00.000Z"), locationConfig());
|
|
202
|
+
const connector = fakeConnector({
|
|
203
|
+
"2026-06-11": [conversation("c-ambiguous", "2026-06-11T15:00:00.000Z", "2026-06-11T15:30:00.000Z")],
|
|
204
|
+
"2026-06-12": [conversation("c-short", "2026-06-12T15:00:00.000Z", "2026-06-12T15:30:00.000Z")],
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
await syncWearableSource(connector, wearableSettings(), wearablesConfig(), { days: 2 }, deps);
|
|
208
|
+
|
|
209
|
+
assert.equal(written.length, 2, "both days written");
|
|
210
|
+
const bodies = written.map((entry) => bodyOf(entry.serialized));
|
|
211
|
+
assert.ok(
|
|
212
|
+
!bodies.some((body) => body.includes("*Location:")),
|
|
213
|
+
`no location line written: ${bodies.join("\n---\n")}`,
|
|
214
|
+
);
|
|
215
|
+
} finally {
|
|
216
|
+
rmSync(memoryDir, { recursive: true, force: true });
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test("wearable sync output is byte-identical without location config or with tagging disabled", async () => {
|
|
221
|
+
const run = async (locationConfigValue?: LocationConfig) => {
|
|
222
|
+
const memoryDir = mkdtempSync(path.join(tmpdir(), "remnic-phase5-zerodiff-"));
|
|
223
|
+
try {
|
|
224
|
+
if (locationConfigValue) {
|
|
225
|
+
await seedLocationDays(memoryDir, {
|
|
226
|
+
"2026-06-11": [segment("2026-06-11T14:30:00.000Z", "2026-06-11T16:00:00.000Z", "Coffee shop")],
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
const { deps, written } = makeSyncDeps(memoryDir, NOW, locationConfigValue);
|
|
230
|
+
const connector = fakeConnector({
|
|
231
|
+
"2026-06-11": [conversation("c1", "2026-06-11T15:00:00.000Z", "2026-06-11T15:30:00.000Z")],
|
|
232
|
+
});
|
|
233
|
+
await syncWearableSource(connector, wearableSettings(), wearablesConfig(), { days: 1 }, deps);
|
|
234
|
+
assert.equal(written.length, 1);
|
|
235
|
+
return bodyOf(written[0].serialized);
|
|
236
|
+
} finally {
|
|
237
|
+
rmSync(memoryDir, { recursive: true, force: true });
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const baseline = await run(undefined);
|
|
242
|
+
const disabled = await run(locationConfig({ tagging: { enabled: false } }));
|
|
243
|
+
assert.equal(disabled, baseline, "tagging disabled → identical transcript body");
|
|
244
|
+
assert.ok(!baseline.includes("*Location:"), "no location line by default");
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test("wearable fill resolves the day bucket across a midnight boundary in the location timezone", async () => {
|
|
248
|
+
const memoryDir = mkdtempSync(path.join(tmpdir(), "remnic-phase5-midnight-"));
|
|
249
|
+
try {
|
|
250
|
+
// America/New_York: conversation 2026-06-30T03:30Z–04:30Z is
|
|
251
|
+
// 23:30–00:30 local, spanning the June-29 / June-30 midnight. The only
|
|
252
|
+
// qualifying segment (00:00–01:00 local) lives on the June-30 bucket —
|
|
253
|
+
// the conversation's END-anchored day, not its start day. The fill must
|
|
254
|
+
// consult both day keys, not just the start day.
|
|
255
|
+
const nyConfig = locationConfig({ timezone: "America/New_York" });
|
|
256
|
+
await seedLocationDays(memoryDir, {
|
|
257
|
+
"2026-06-30": [segment("2026-06-30T04:00:00.000Z", "2026-06-30T05:00:00.000Z", "Late diner")],
|
|
258
|
+
});
|
|
259
|
+
const { deps, written } = makeSyncDeps(memoryDir, new Date("2026-07-01T03:00:00.000Z"), nyConfig);
|
|
260
|
+
const connector = fakeConnector({
|
|
261
|
+
"2026-06-30": [conversation("c-span", "2026-06-30T03:30:00.000Z", "2026-06-30T04:30:00.000Z")],
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
await syncWearableSource(
|
|
265
|
+
connector,
|
|
266
|
+
wearableSettings(),
|
|
267
|
+
wearablesConfig("America/New_York"),
|
|
268
|
+
{ date: "2026-06-30" },
|
|
269
|
+
deps,
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
assert.equal(written.length, 1);
|
|
273
|
+
const body = bodyOf(written[0].serialized);
|
|
274
|
+
assert.ok(body.includes("*Location: Late diner*"), `cross-midnight segment matched: ${body}`);
|
|
275
|
+
} finally {
|
|
276
|
+
rmSync(memoryDir, { recursive: true, force: true });
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// ── Day summary opt-in ──────────────────────────────────────────────────────
|
|
281
|
+
|
|
282
|
+
function opsCoordinator(storage: StorageManager, configOverrides: Partial<PluginConfig>) {
|
|
283
|
+
return new WorkspaceOpsCoordinator({
|
|
284
|
+
config: {
|
|
285
|
+
defaultNamespace: "default",
|
|
286
|
+
daySummaryTimezone: "UTC",
|
|
287
|
+
...configOverrides,
|
|
288
|
+
} as unknown as PluginConfig,
|
|
289
|
+
storageRouter: {
|
|
290
|
+
storageFor: async () => storage,
|
|
291
|
+
},
|
|
292
|
+
} as unknown as WorkspaceOpsDeps);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
test("gatherTodayFacts appends location context only when requested and gated", async () => {
|
|
296
|
+
const gather = async (options: { includeLocation?: boolean; location?: LocationConfig }) => {
|
|
297
|
+
const root = mkdtempSync(path.join(tmpdir(), "remnic-phase5-summary-"));
|
|
298
|
+
try {
|
|
299
|
+
const storage = new StorageManager(root);
|
|
300
|
+
await storage.writeMemory("fact", "Shipped the location wiring.", { source: "test" });
|
|
301
|
+
if (options.location) {
|
|
302
|
+
const day = new Date().toISOString().slice(0, 10);
|
|
303
|
+
await seedLocationDays(root, {
|
|
304
|
+
[day]: [segment(`${day}T09:00:00.000Z`, `${day}T17:00:00.000Z`, "Office", "work")],
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const coordinator = opsCoordinator(storage, options.location ? { location: options.location } : {});
|
|
308
|
+
return await coordinator.gatherTodayFacts(undefined, {
|
|
309
|
+
now: new Date(),
|
|
310
|
+
timeZone: "UTC",
|
|
311
|
+
...(options.includeLocation !== undefined ? { includeLocation: options.includeLocation } : {}),
|
|
312
|
+
});
|
|
313
|
+
} finally {
|
|
314
|
+
rmSync(root, { recursive: true, force: true });
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
// Each gather run writes a fresh fact id/timestamp header; normalize it
|
|
319
|
+
// away so byte-comparisons isolate the location delta.
|
|
320
|
+
const normalized = (gathered: string) => gathered.replace(/^\[fact-[^\]]*\] \([^)]*\)/gm, "[fact]");
|
|
321
|
+
|
|
322
|
+
const enabled = locationConfig();
|
|
323
|
+
const baseline = await gather({});
|
|
324
|
+
const withStateNoFlag = await gather({ location: enabled });
|
|
325
|
+
assert.equal(normalized(withStateNoFlag), normalized(baseline), "no request flag → byte-identical gathered summary");
|
|
326
|
+
|
|
327
|
+
const withFlagNoState = await gather({ includeLocation: true });
|
|
328
|
+
assert.equal(normalized(withFlagNoState), normalized(baseline), "flag without location state → byte-identical");
|
|
329
|
+
|
|
330
|
+
const withFlag = await gather({ includeLocation: true, location: enabled });
|
|
331
|
+
assert.ok(withFlag.includes("## Location context"), "opt-in adds the location section");
|
|
332
|
+
assert.ok(withFlag.includes("- Office: 8h 00m"), "labels and durations only");
|
|
333
|
+
|
|
334
|
+
const flagButTaggingOff = await gather({
|
|
335
|
+
includeLocation: true,
|
|
336
|
+
location: locationConfig({ tagging: { enabled: false } }),
|
|
337
|
+
});
|
|
338
|
+
assert.equal(normalized(flagButTaggingOff), normalized(baseline), "flag with tagging disabled → byte-identical");
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// ── Briefing opt-in ─────────────────────────────────────────────────────────
|
|
342
|
+
|
|
343
|
+
test("briefingLocationSection is opt-in, start-day anchored, and labels-only", async () => {
|
|
344
|
+
const root = mkdtempSync(path.join(tmpdir(), "remnic-phase5-briefing-"));
|
|
345
|
+
try {
|
|
346
|
+
const day = new Date().toISOString().slice(0, 10);
|
|
347
|
+
await seedLocationDays(root, {
|
|
348
|
+
[day]: [
|
|
349
|
+
segment(`${day}T08:00:00.000Z`, `${day}T18:00:00.000Z`, "HQ", "work"),
|
|
350
|
+
segment(`${day}T18:00:00.000Z`, `${day}T19:00:00.000Z`, "Commuter rail", "transit"),
|
|
351
|
+
],
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
const gatedOff = await briefingLocationSection(
|
|
355
|
+
root,
|
|
356
|
+
new Date().toISOString(),
|
|
357
|
+
locationConfig({ tagging: { enabled: false } }),
|
|
358
|
+
);
|
|
359
|
+
assert.equal(gatedOff, null, "tagging disabled → no section");
|
|
360
|
+
|
|
361
|
+
const section = await briefingLocationSection(root, new Date().toISOString(), locationConfig());
|
|
362
|
+
assert.ok(section, "gated on → section rendered");
|
|
363
|
+
assert.ok(section.includes("## Location context"));
|
|
364
|
+
assert.ok(section.includes("- HQ: 10h 00m"), "work place rendered with duration");
|
|
365
|
+
assert.ok(!section.includes("Commuter rail"), "transit-only place excluded");
|
|
366
|
+
|
|
367
|
+
const none = await briefingLocationSection(
|
|
368
|
+
root,
|
|
369
|
+
new Date(Date.now() - 90 * 24 * 3600 * 1000).toISOString(),
|
|
370
|
+
locationConfig(),
|
|
371
|
+
);
|
|
372
|
+
assert.equal(none, null, "window start on a day without segments → no section");
|
|
373
|
+
} finally {
|
|
374
|
+
rmSync(root, { recursive: true, force: true });
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// ── Privacy ─────────────────────────────────────────────────────────────────
|
|
379
|
+
|
|
380
|
+
test("phase-5 outputs never contain coordinates or raw location records", async () => {
|
|
381
|
+
const root = mkdtempSync(path.join(tmpdir(), "remnic-phase5-privacy-"));
|
|
382
|
+
try {
|
|
383
|
+
const day = new Date().toISOString().slice(0, 10);
|
|
384
|
+
// Segment places carry coordinates (as if retainCoordinates had been on
|
|
385
|
+
// at ingestion) — every phase-5 surface must still render labels only.
|
|
386
|
+
await seedLocationDays(root, {
|
|
387
|
+
[day]: [segment(`${day}T08:00:00.000Z`, `${day}T18:00:00.000Z`, "HQ", "work")],
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const section = await briefingLocationSection(root, new Date().toISOString(), locationConfig());
|
|
391
|
+
assert.ok(section);
|
|
392
|
+
assert.ok(!/\d+\.\d{3,}/.test(section), `no coordinate-like numbers: ${section}`);
|
|
393
|
+
assert.ok(!section.includes("startUtc") && !section.includes("observationCount"), "no raw record fields");
|
|
394
|
+
|
|
395
|
+
const storage = new StorageManager(root);
|
|
396
|
+
await storage.writeMemory("fact", "Privacy probe fact.", { source: "test" });
|
|
397
|
+
const coordinator = opsCoordinator(storage, { location: locationConfig() });
|
|
398
|
+
const gathered = await coordinator.gatherTodayFacts(undefined, {
|
|
399
|
+
now: new Date(),
|
|
400
|
+
timeZone: "UTC",
|
|
401
|
+
includeLocation: true,
|
|
402
|
+
});
|
|
403
|
+
assert.ok(!gathered.includes("60.1699") && !gathered.includes("24.9384"), "no coordinates in day-summary input");
|
|
404
|
+
assert.ok(!gathered.includes("latitude") && !gathered.includes("longitude"), "no coordinate field names");
|
|
405
|
+
} finally {
|
|
406
|
+
rmSync(root, { recursive: true, force: true });
|
|
407
|
+
}
|
|
408
|
+
});
|
package/src/location/tagging.ts
CHANGED
|
@@ -275,3 +275,61 @@ export async function renderDayLocationContext(
|
|
|
275
275
|
});
|
|
276
276
|
return `## Location context\n\n${lines.join("\n")}`;
|
|
277
277
|
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Location context for a briefing (issue #2925): the place names of the
|
|
281
|
+
* local day containing the briefing window's start, bucketed in the
|
|
282
|
+
* location config's own timezone (the store's bucketing zone). Opt-in and
|
|
283
|
+
* labels-only — the caller decides whether to include it.
|
|
284
|
+
*/
|
|
285
|
+
export async function briefingLocationSection(
|
|
286
|
+
memoryDir: string,
|
|
287
|
+
windowStartUtc: string,
|
|
288
|
+
config: LocationConfig,
|
|
289
|
+
): Promise<string | null> {
|
|
290
|
+
return renderDayLocationContext(
|
|
291
|
+
memoryDir,
|
|
292
|
+
localDayKey(windowStartUtc, config.timezone),
|
|
293
|
+
config,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export async function applyBriefingLocationContext<
|
|
298
|
+
T extends { markdown: string; json: Record<string, unknown> },
|
|
299
|
+
>(
|
|
300
|
+
result: T,
|
|
301
|
+
includeLocation: boolean | undefined,
|
|
302
|
+
memoryDir: string,
|
|
303
|
+
windowStartUtc: string,
|
|
304
|
+
location: LocationConfig,
|
|
305
|
+
): Promise<T> {
|
|
306
|
+
if (includeLocation !== true || !locationTaggingEnabled(location)) return result;
|
|
307
|
+
const section = await briefingLocationSection(memoryDir, windowStartUtc, location);
|
|
308
|
+
if (!section) return result;
|
|
309
|
+
return {
|
|
310
|
+
...result,
|
|
311
|
+
markdown: `${result.markdown}\n\n${section}\n`,
|
|
312
|
+
json: { ...result.json, locationContext: section },
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Opt-in matched-place-name context (issue #2925), shared by the access
|
|
318
|
+
* request surfaces (day summary and briefing). Absent or false keeps the
|
|
319
|
+
* output byte-identical.
|
|
320
|
+
*/
|
|
321
|
+
export interface LocationContextRequestOptions {
|
|
322
|
+
/** Opt-in matched-place-name context appended to the summary or briefing output. */
|
|
323
|
+
includeLocation?: boolean;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Auto-gather options for the day summary (issue #2925): the caller's
|
|
328
|
+
* timezone plus the strictly-opt-in location flag. Only the literal
|
|
329
|
+
* `true` opts in, matching the transport schemas' boolean contract.
|
|
330
|
+
*/
|
|
331
|
+
export function daySummaryAutoOptions(
|
|
332
|
+
request: LocationContextRequestOptions & { timeZone?: string },
|
|
333
|
+
): { timeZone?: string; includeLocation: boolean } {
|
|
334
|
+
return { timeZone: request.timeZone, includeLocation: request.includeLocation === true };
|
|
335
|
+
}
|
|
@@ -325,6 +325,8 @@ export const DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS = 10_000;
|
|
|
325
325
|
export type DaySummaryGatherOptions = {
|
|
326
326
|
timeZone?: string;
|
|
327
327
|
now?: Date;
|
|
328
|
+
/** Opt-in location context (issue #2925); false/absent keeps output byte-identical. */
|
|
329
|
+
includeLocation?: boolean;
|
|
328
330
|
};
|
|
329
331
|
|
|
330
332
|
export function normalizeIanaTimeZone(value: unknown): string | undefined {
|
|
@@ -28,6 +28,8 @@ import { LocalLlmClient } from "../local-llm.js";
|
|
|
28
28
|
import { log } from "../logger.js";
|
|
29
29
|
import type { NamespaceMaintenanceFanoutRunnerContext } from "../maintenance/namespace-maintenance-fanout.js";
|
|
30
30
|
import type { NamespaceMaintenanceSummary } from "../maintenance/namespace-planner.js";
|
|
31
|
+
import { localDayKey } from "../location/intervals.js";
|
|
32
|
+
import { renderDayLocationContext } from "../location/tagging.js";
|
|
31
33
|
import { type PatternReinforcementResult, runPatternReinforcement } from "../maintenance/pattern-reinforcement.js";
|
|
32
34
|
import { evaluateMemoryActionPolicy } from "../memory-action-policy.js";
|
|
33
35
|
import { NamespaceStorageRouter } from "../namespaces/storage.js";
|
|
@@ -454,6 +456,17 @@ export class WorkspaceOpsCoordinator {
|
|
|
454
456
|
}
|
|
455
457
|
}
|
|
456
458
|
|
|
459
|
+
if (options.includeLocation === true && this.deps.config.location) {
|
|
460
|
+
const section = await renderDayLocationContext(
|
|
461
|
+
storage.dir,
|
|
462
|
+
localDayKey(now.toISOString(), this.deps.config.location.timezone),
|
|
463
|
+
this.deps.config.location,
|
|
464
|
+
);
|
|
465
|
+
if (section) {
|
|
466
|
+
formatted += `\n\n${section}`;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
457
470
|
log.info(
|
|
458
471
|
`gatherTodayFacts: collected ${facts.length} facts, ${hourlySummaries.length} hourly summaries for ${targetLocalDate} (${timeZone}, ${formatted.length} chars)`,
|
|
459
472
|
);
|
|
@@ -636,6 +649,7 @@ export class WorkspaceOpsCoordinator {
|
|
|
636
649
|
service = new WearablesService({
|
|
637
650
|
config: this.deps.config.wearables,
|
|
638
651
|
getStorage: async () => await this.deps.getStorageForNamespace(namespace),
|
|
652
|
+
locationConfig: this.deps.config.location,
|
|
639
653
|
extract: (turns) => this.deps.extraction.extract(turns),
|
|
640
654
|
// Smart memoryMode runs candidates through the SAME extraction
|
|
641
655
|
// judge (cache + defer counters included) the live extraction
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* write for the run has succeeded.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { fillWearableConversationLocations } from "../location/tagging.js";
|
|
18
19
|
import { cleanConversation } from "./cleanup.js";
|
|
19
20
|
import { describeErrorForOperator, WearablesInputError } from "./errors.js";
|
|
20
21
|
import {
|
|
@@ -50,6 +51,7 @@ import {
|
|
|
50
51
|
saveSyncState,
|
|
51
52
|
updateSourceSyncState,
|
|
52
53
|
} from "./sync-state.js";
|
|
54
|
+
import type { LocationConfig } from "../location/types.js";
|
|
53
55
|
import type {
|
|
54
56
|
WearableConversation,
|
|
55
57
|
WearableSourceConnector,
|
|
@@ -122,6 +124,11 @@ export interface WearableSyncDeps {
|
|
|
122
124
|
listSupportMemories?(): Promise<Array<{ id: string; content: string }>>;
|
|
123
125
|
/** Clock injection for tests. */
|
|
124
126
|
now?: () => Date;
|
|
127
|
+
/**
|
|
128
|
+
* Location config for the missing-only conversation location fill
|
|
129
|
+
* (issue #2925). Absent, or location tagging disabled, changes nothing.
|
|
130
|
+
*/
|
|
131
|
+
locationConfig?: LocationConfig;
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
/** Format a Date as YYYY-MM-DD in the given IANA timezone. */
|
|
@@ -382,6 +389,18 @@ export async function syncWearableSource(
|
|
|
382
389
|
summary.redactions += cleaned.redactions;
|
|
383
390
|
summary.correctionsApplied += cleaned.correctionsApplied;
|
|
384
391
|
|
|
392
|
+
// Missing-only location fill (issue #2925): run before the body is
|
|
393
|
+
// composed so a qualifying dominant-overlap place reaches the day
|
|
394
|
+
// transcript and memory headers exactly like a provider-supplied
|
|
395
|
+
// location would. Source-provided values are never overwritten, and
|
|
396
|
+
// the helper no-ops unless both location gates are on.
|
|
397
|
+
if (deps.locationConfig) {
|
|
398
|
+
await fillWearableConversationLocations(cleaned.conversations, {
|
|
399
|
+
memoryDir: deps.memoryDir,
|
|
400
|
+
config: deps.locationConfig,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
385
404
|
if (fetched.conversations.length === 0) {
|
|
386
405
|
// No provider data at all. A transient provider hiccup can
|
|
387
406
|
// legitimately produce an empty result, so an existing stored
|
package/src/wearables/service.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from "./corrections.js";
|
|
14
14
|
import { describeErrorForOperator, WearablesInputError } from "./errors.js";
|
|
15
15
|
import { inferMemoryStatus } from "../memory-lifecycle-ledger-utils.js";
|
|
16
|
+
import type { LocationConfig } from "../location/types.js";
|
|
16
17
|
import { isSupportPassportPrivateMemory } from "../support-passport/card-projection.js";
|
|
17
18
|
import {
|
|
18
19
|
bodyIsEscaped,
|
|
@@ -143,6 +144,12 @@ export interface WearablesServiceDeps {
|
|
|
143
144
|
* fails the sync.
|
|
144
145
|
*/
|
|
145
146
|
onDaysSynced?: (days: readonly string[]) => void | Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Location config for the missing-only conversation location fill
|
|
149
|
+
* (issue #2925). Absent changes nothing; the fill itself stays gated
|
|
150
|
+
* on the location tagging flags.
|
|
151
|
+
*/
|
|
152
|
+
locationConfig?: LocationConfig;
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
export interface WearableTranscriptSearchResult {
|
|
@@ -351,6 +358,7 @@ export class WearablesService {
|
|
|
351
358
|
options,
|
|
352
359
|
{
|
|
353
360
|
memoryDir: storage.dir,
|
|
361
|
+
locationConfig: this.deps.locationConfig,
|
|
354
362
|
readDayContentHash: async (source, date) => {
|
|
355
363
|
const raw = await storage.readWearableDayTranscript(source, date);
|
|
356
364
|
if (raw === null) return null;
|