@remnic/core 9.65.6 → 9.65.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +11 -11
- package/dist/access-admin-ops-surface.js +31 -31
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +11 -11
- package/dist/access-authorization-probe.js +32 -32
- package/dist/access-boundary.d.ts +11 -11
- package/dist/access-boundary.js +31 -31
- package/dist/access-cli.js +111 -106
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +11 -11
- package/dist/access-extraction-force-flush.js +31 -31
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +11 -11
- package/dist/access-http-lifecycle-flush.d.ts +11 -11
- package/dist/access-http-offline-stream.d.ts +11 -11
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +33 -33
- package/dist/access-http.d.ts +13 -18
- package/dist/access-http.js +50 -48
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +31 -31
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +31 -31
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +42 -40
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-D_6mo8ms.d.ts → access-namespace-preflight-8VYKmRX0.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +31 -31
- package/dist/access-observe-write-surface.d.ts +11 -11
- package/dist/access-observe-write-surface.js +31 -31
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-operations-batch.js +34 -34
- package/dist/access-operations.d.ts +12 -12
- package/dist/access-operations.js +39 -37
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +31 -31
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +31 -31
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +31 -31
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-sbiNS5UB.d.ts → access-service-Crk__Git.d.ts} +8 -8
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +31 -31
- package/dist/access-surface-catalog.d.ts +11 -11
- package/dist/access-surface-catalog.js +43 -33
- 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 +4 -4
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +10 -10
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{catalog-DO_7zfkv.d.ts → catalog-DybwVNW3.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +13 -13
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-NZPFCP5A.js → chunk-2PSX5BJU.js} +2 -2
- package/dist/chunk-3BCULS4U.js +1093 -0
- package/dist/chunk-3BCULS4U.js.map +1 -0
- package/dist/{chunk-W6J4POB6.js → chunk-3RI5Y7KU.js} +2 -2
- package/dist/{chunk-H7BZBSP6.js → chunk-52II7PB6.js} +4 -4
- package/dist/{chunk-IF4EY26E.js → chunk-5DH6PG4B.js} +2 -2
- package/dist/{chunk-M4AHBM72.js → chunk-5HERQ5FX.js} +10 -10
- package/dist/{chunk-IRXMJLTW.js → chunk-5HK3CJAR.js} +2 -2
- package/dist/{chunk-XAWIL7TC.js → chunk-5S4LQOPE.js} +2 -2
- package/dist/{chunk-IDQ6DKXC.js → chunk-5VPQSRQO.js} +3 -3
- package/dist/{chunk-ROEAEANL.js → chunk-6CPUQ5D6.js} +10 -10
- package/dist/{chunk-SR7JIRAR.js → chunk-7F27PCSN.js} +2 -2
- package/dist/{chunk-7OZSHBWK.js → chunk-7TCGNUVP.js} +2 -2
- package/dist/{chunk-KBOG7FJV.js → chunk-7WR462EM.js} +2 -2
- package/dist/{chunk-AYAZWXJI.js → chunk-A32YEQAM.js} +2 -2
- package/dist/{chunk-5GIZM4RX.js → chunk-ACOC27BB.js} +2 -2
- package/dist/{chunk-5W7MKXMU.js → chunk-AFR6AIM4.js} +144 -78
- package/dist/chunk-AFR6AIM4.js.map +1 -0
- package/dist/{chunk-OMZLBT4B.js → chunk-ANJXPFRS.js} +47 -26
- package/dist/chunk-ANJXPFRS.js.map +1 -0
- package/dist/{chunk-FC7TIRFS.js → chunk-AX7UXCHJ.js} +6 -1
- package/dist/chunk-AX7UXCHJ.js.map +1 -0
- package/dist/{chunk-6LS5OX3U.js → chunk-BJTHRFFC.js} +6 -6
- package/dist/chunk-BWGCOLEL.js +61 -0
- package/dist/chunk-BWGCOLEL.js.map +1 -0
- package/dist/{chunk-PGW64IFQ.js → chunk-CFGU52XJ.js} +2 -2
- package/dist/{chunk-DPNXADEI.js → chunk-D4QVPP3G.js} +2 -2
- package/dist/{chunk-2RXUZVPU.js → chunk-EOHKUWXW.js} +2 -2
- package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
- package/dist/{chunk-ZK4BFABK.js → chunk-F635GAL7.js} +4 -4
- package/dist/{chunk-HWVNYNIV.js → chunk-F6QHHRWP.js} +2 -2
- package/dist/{chunk-YUTTMSC7.js → chunk-FMQ4MOQO.js} +89 -26
- package/dist/chunk-FMQ4MOQO.js.map +1 -0
- package/dist/{chunk-LDBFXD4F.js → chunk-FP7YTTVO.js} +3 -1
- package/dist/chunk-FP7YTTVO.js.map +1 -0
- package/dist/{chunk-O4BAGJDN.js → chunk-GEPACVWN.js} +2 -2
- package/dist/{chunk-XZBXINXZ.js → chunk-GIC6BASP.js} +4 -4
- package/dist/{chunk-PP7R754B.js → chunk-GPFZFCRN.js} +1 -1
- package/dist/{chunk-LSYD7GHZ.js → chunk-GTSVEEP3.js} +2 -2
- package/dist/{chunk-RQ2EQRRR.js → chunk-I4343FIA.js} +79 -6
- package/dist/chunk-I4343FIA.js.map +1 -0
- package/dist/{chunk-YWBOOBDP.js → chunk-I7EX6KSH.js} +58 -58
- package/dist/{chunk-3I22VWB3.js → chunk-IP4ZNT4U.js} +2 -2
- package/dist/{chunk-AXGFOFNY.js → chunk-IY7UXD3J.js} +2 -2
- package/dist/{chunk-6FUMA6AA.js → chunk-JAQXUGLN.js} +2 -2
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/chunk-JCCWJHOP.js +240 -0
- package/dist/chunk-JCCWJHOP.js.map +1 -0
- package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-D2YNNDML.js → chunk-KWIGDKM2.js} +2 -2
- package/dist/{chunk-2JHRCWHT.js → chunk-LLQCM2U2.js} +85 -85
- package/dist/{chunk-OLBZ2WGG.js → chunk-LTBKKSCX.js} +2 -2
- package/dist/{chunk-RACZB5HT.js → chunk-N37X5RU7.js} +4 -4
- package/dist/{chunk-FEO2CDXR.js → chunk-NG3MBQV4.js} +2 -2
- package/dist/{chunk-AG46P24C.js → chunk-NNBZS3DY.js} +4 -4
- package/dist/{chunk-JGG5HVI2.js → chunk-OPGL46PX.js} +2 -2
- package/dist/{chunk-OUKBMQ2O.js → chunk-PD66CVSD.js} +2 -2
- package/dist/{chunk-7SSRXEZJ.js → chunk-PDDSFELN.js} +2 -2
- package/dist/{chunk-MVIYRRVJ.js → chunk-PMVPCZJZ.js} +5 -5
- package/dist/{chunk-D35XLYQ7.js → chunk-RGCF4XNH.js} +9 -9
- package/dist/{chunk-PNAGNVGK.js → chunk-RQE4TITU.js} +35 -30
- package/dist/chunk-RQE4TITU.js.map +1 -0
- package/dist/{chunk-X2DWBWOX.js → chunk-S3K2CIK5.js} +2 -2
- package/dist/{chunk-TWBQQ3FT.js → chunk-SEA6M7SS.js} +2 -2
- package/dist/{chunk-DYO24BNB.js → chunk-SVVIASVX.js} +2 -2
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-4K7IW3F7.js → chunk-UD7UNYRD.js} +34 -3
- package/dist/chunk-UD7UNYRD.js.map +1 -0
- package/dist/chunk-ULM7JCDH.js +154 -0
- package/dist/chunk-ULM7JCDH.js.map +1 -0
- package/dist/{chunk-NLUCDKLT.js → chunk-VKCAHCBI.js} +2 -2
- package/dist/{chunk-BXXOPKT5.js → chunk-VXVZ2GM3.js} +2 -2
- package/dist/chunk-W2UOAATB.js +521 -0
- package/dist/chunk-W2UOAATB.js.map +1 -0
- package/dist/{chunk-JFWZRUKP.js → chunk-WTOZBZNN.js} +3 -3
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-5TG4MU2U.js → chunk-YKWFK7XA.js} +5 -5
- package/dist/{chunk-BIJAWZYW.js → chunk-YMOPYG3K.js} +6 -6
- package/dist/{chunk-XUZ5CIEE.js → chunk-YRVAKONL.js} +1 -1
- package/dist/{chunk-53MZQEBD.js → chunk-YWSQD2IB.js} +2 -2
- package/dist/{chunk-US4IRASK.js → chunk-Z4U3UN56.js} +2 -2
- package/dist/{chunk-QMZY3GG6.js → chunk-ZAOHJDKH.js} +3 -3
- package/dist/{chunk-ZXUZ54Z5.js → chunk-ZIJDI4CP.js} +2 -2
- package/dist/{cli-Bfgo0n1L.d.ts → cli-B322UMvB.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +75 -74
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/coding/pre-action-gate.js +2 -2
- 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 +4 -4
- 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 +3 -3
- 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/cross-lingual-recall.d.ts +1 -1
- package/dist/dashboard-runtime.js +2 -2
- 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-D23_x-s5.d.ts → dependency-propagation-delivery-BGcNairQ.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/eval-trajectory-contracts.d.ts +256 -0
- package/dist/eval-trajectory-contracts.js +56 -0
- package/dist/eval-trajectory-store.d.ts +39 -0
- package/dist/eval-trajectory-store.js +19 -0
- package/dist/eval-trajectory-store.js.map +1 -0
- package/dist/eval-trajectory.d.ts +67 -0
- package/dist/eval-trajectory.js +46 -0
- package/dist/eval-trajectory.js.map +1 -0
- package/dist/event-order-recall.js +2 -2
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/external-wiki-access.d.ts +11 -11
- package/dist/external-wiki-access.js +32 -32
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +11 -11
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +12 -12
- 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-decay-FXGELBFA.js → graph-edge-decay-A4SDFMMS.js} +4 -4
- package/dist/graph-edge-decay-A4SDFMMS.js.map +1 -0
- 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-snapshot.js +3 -3
- package/dist/graph.d.ts +1 -1
- package/dist/graph.js +3 -3
- 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--QhGIXF2.d.ts → index-By2QUAMh.d.ts} +2 -2
- package/dist/index.d.ts +26 -23
- package/dist/index.js +184 -142
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +13 -13
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/location/index.d.ts +128 -1
- package/dist/location/index.js +60 -750
- package/dist/location/index.js.map +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-PFvY1Pw_.d.ts → maintenance-Dm2McrIx.d.ts} +4 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -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-controller.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-subject-cli.d.ts +11 -11
- package/dist/memory-subject.d.ts +11 -11
- package/dist/memory-worth-outcomes.d.ts +47 -3
- package/dist/memory-worth-outcomes.js +5 -3
- 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 +24 -24
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +18 -16
- package/dist/{orchestrator-4wzJrPVm.d.ts → orchestrator-Co1DyfuP.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +111 -106
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CgXgdIrF.d.ts → pipeline-DotMnb6y.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-BP3VQDl5.d.ts → public-http-PJRtnSi-.d.ts} +1 -1
- package/dist/{qmd-BppGGxsi.d.ts → qmd-BP0n11fR.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-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-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/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +5 -5
- 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-ChZUtxDU.d.ts → scope-profiles-6ChZKTy-.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-mSPwQSmF.d.ts → semantic-consolidation-DziYcW5J.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-BICWLwSP.d.ts → service-C7rIBuK_.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 +10 -10
- package/dist/{storage-B7urx1K3.d.ts → storage-B1hEx8Xg.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +9 -9
- package/dist/subject-config.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +14 -14
- package/dist/support-passport/index.js +34 -34
- 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-ETU5N6nB.d.ts → types-BHDNxGTT.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +10 -10
- package/dist/who-knows-cli.d.ts +11 -11
- package/dist/who-knows-cli.js +11 -11
- package/dist/who-knows.d.ts +11 -11
- package/dist/who-knows.js +10 -10
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-boundary.ts +5 -0
- package/src/access-http.ts +15 -16
- package/src/access-mcp-output-schemas.ts +5 -0
- package/src/access-mcp.ts +6 -6
- package/src/access-operations.ts +2 -0
- package/src/access-surface-catalog.ts +10 -0
- package/src/eval-trajectory-contracts.ts +411 -0
- package/src/eval-trajectory-store.ts +306 -0
- package/src/eval-trajectory.test.ts +534 -0
- package/src/eval-trajectory.ts +773 -0
- package/src/index.ts +2 -0
- package/src/location/access-operations.ts +84 -0
- package/src/location/http-glue.test.ts +100 -0
- package/src/location/http-glue.ts +85 -0
- package/src/location/index.ts +3 -0
- package/src/location/mcp-tools.ts +82 -0
- package/src/location/provider-setup.test.ts +106 -0
- package/src/location/provider-setup.ts +103 -0
- package/src/location/scheduler.test.ts +113 -0
- package/src/location/scheduler.ts +98 -0
- package/src/location/surfaces.test.ts +241 -0
- package/src/location/surfaces.ts +329 -0
- package/src/maintenance/day-summary-cron.ts +45 -0
- package/src/mcp-read-only-tools.ts +2 -0
- package/src/memory-worth-outcomes.test.ts +53 -18
- package/src/memory-worth-outcomes.ts +91 -9
- package/src/orchestration/maintenance.ts +22 -30
- package/src/wearables/http-glue.ts +28 -0
- package/dist/chunk-4K7IW3F7.js.map +0 -1
- package/dist/chunk-5W7MKXMU.js.map +0 -1
- package/dist/chunk-FC7TIRFS.js.map +0 -1
- package/dist/chunk-LDBFXD4F.js.map +0 -1
- package/dist/chunk-OMZLBT4B.js.map +0 -1
- package/dist/chunk-PNAGNVGK.js.map +0 -1
- package/dist/chunk-RQ2EQRRR.js.map +0 -1
- package/dist/chunk-YUTTMSC7.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-NZPFCP5A.js.map → chunk-2PSX5BJU.js.map} +0 -0
- /package/dist/{chunk-W6J4POB6.js.map → chunk-3RI5Y7KU.js.map} +0 -0
- /package/dist/{chunk-H7BZBSP6.js.map → chunk-52II7PB6.js.map} +0 -0
- /package/dist/{chunk-IF4EY26E.js.map → chunk-5DH6PG4B.js.map} +0 -0
- /package/dist/{chunk-M4AHBM72.js.map → chunk-5HERQ5FX.js.map} +0 -0
- /package/dist/{chunk-IRXMJLTW.js.map → chunk-5HK3CJAR.js.map} +0 -0
- /package/dist/{chunk-XAWIL7TC.js.map → chunk-5S4LQOPE.js.map} +0 -0
- /package/dist/{chunk-IDQ6DKXC.js.map → chunk-5VPQSRQO.js.map} +0 -0
- /package/dist/{chunk-ROEAEANL.js.map → chunk-6CPUQ5D6.js.map} +0 -0
- /package/dist/{chunk-SR7JIRAR.js.map → chunk-7F27PCSN.js.map} +0 -0
- /package/dist/{chunk-7OZSHBWK.js.map → chunk-7TCGNUVP.js.map} +0 -0
- /package/dist/{chunk-KBOG7FJV.js.map → chunk-7WR462EM.js.map} +0 -0
- /package/dist/{chunk-AYAZWXJI.js.map → chunk-A32YEQAM.js.map} +0 -0
- /package/dist/{chunk-5GIZM4RX.js.map → chunk-ACOC27BB.js.map} +0 -0
- /package/dist/{chunk-6LS5OX3U.js.map → chunk-BJTHRFFC.js.map} +0 -0
- /package/dist/{chunk-PGW64IFQ.js.map → chunk-CFGU52XJ.js.map} +0 -0
- /package/dist/{chunk-DPNXADEI.js.map → chunk-D4QVPP3G.js.map} +0 -0
- /package/dist/{chunk-2RXUZVPU.js.map → chunk-EOHKUWXW.js.map} +0 -0
- /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
- /package/dist/{chunk-ZK4BFABK.js.map → chunk-F635GAL7.js.map} +0 -0
- /package/dist/{chunk-HWVNYNIV.js.map → chunk-F6QHHRWP.js.map} +0 -0
- /package/dist/{chunk-O4BAGJDN.js.map → chunk-GEPACVWN.js.map} +0 -0
- /package/dist/{chunk-XZBXINXZ.js.map → chunk-GIC6BASP.js.map} +0 -0
- /package/dist/{chunk-PP7R754B.js.map → chunk-GPFZFCRN.js.map} +0 -0
- /package/dist/{chunk-LSYD7GHZ.js.map → chunk-GTSVEEP3.js.map} +0 -0
- /package/dist/{chunk-YWBOOBDP.js.map → chunk-I7EX6KSH.js.map} +0 -0
- /package/dist/{chunk-3I22VWB3.js.map → chunk-IP4ZNT4U.js.map} +0 -0
- /package/dist/{chunk-AXGFOFNY.js.map → chunk-IY7UXD3J.js.map} +0 -0
- /package/dist/{chunk-6FUMA6AA.js.map → chunk-JAQXUGLN.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-D2YNNDML.js.map → chunk-KWIGDKM2.js.map} +0 -0
- /package/dist/{chunk-2JHRCWHT.js.map → chunk-LLQCM2U2.js.map} +0 -0
- /package/dist/{chunk-OLBZ2WGG.js.map → chunk-LTBKKSCX.js.map} +0 -0
- /package/dist/{chunk-RACZB5HT.js.map → chunk-N37X5RU7.js.map} +0 -0
- /package/dist/{chunk-FEO2CDXR.js.map → chunk-NG3MBQV4.js.map} +0 -0
- /package/dist/{chunk-AG46P24C.js.map → chunk-NNBZS3DY.js.map} +0 -0
- /package/dist/{chunk-JGG5HVI2.js.map → chunk-OPGL46PX.js.map} +0 -0
- /package/dist/{chunk-OUKBMQ2O.js.map → chunk-PD66CVSD.js.map} +0 -0
- /package/dist/{chunk-7SSRXEZJ.js.map → chunk-PDDSFELN.js.map} +0 -0
- /package/dist/{chunk-MVIYRRVJ.js.map → chunk-PMVPCZJZ.js.map} +0 -0
- /package/dist/{chunk-D35XLYQ7.js.map → chunk-RGCF4XNH.js.map} +0 -0
- /package/dist/{chunk-X2DWBWOX.js.map → chunk-S3K2CIK5.js.map} +0 -0
- /package/dist/{chunk-TWBQQ3FT.js.map → chunk-SEA6M7SS.js.map} +0 -0
- /package/dist/{chunk-DYO24BNB.js.map → chunk-SVVIASVX.js.map} +0 -0
- /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-NLUCDKLT.js.map → chunk-VKCAHCBI.js.map} +0 -0
- /package/dist/{chunk-BXXOPKT5.js.map → chunk-VXVZ2GM3.js.map} +0 -0
- /package/dist/{chunk-JFWZRUKP.js.map → chunk-WTOZBZNN.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-5TG4MU2U.js.map → chunk-YKWFK7XA.js.map} +0 -0
- /package/dist/{chunk-BIJAWZYW.js.map → chunk-YMOPYG3K.js.map} +0 -0
- /package/dist/{chunk-XUZ5CIEE.js.map → chunk-YRVAKONL.js.map} +0 -0
- /package/dist/{chunk-53MZQEBD.js.map → chunk-YWSQD2IB.js.map} +0 -0
- /package/dist/{chunk-US4IRASK.js.map → chunk-Z4U3UN56.js.map} +0 -0
- /package/dist/{chunk-QMZY3GG6.js.map → chunk-ZAOHJDKH.js.map} +0 -0
- /package/dist/{chunk-ZXUZ54Z5.js.map → chunk-ZIJDI4CP.js.map} +0 -0
- /package/dist/{graph-edge-decay-FXGELBFA.js.map → eval-trajectory-contracts.js.map} +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location auto-sync scheduler regression (issue #2047): the maintenance
|
|
3
|
+
* scheduler arms this only when enabled; here we pin the timer contract —
|
|
4
|
+
* ticks run the shared sync runner, overlap is skipped not queued, and stop
|
|
5
|
+
* cancels + drains.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import assert from "node:assert/strict";
|
|
9
|
+
import test from "node:test";
|
|
10
|
+
|
|
11
|
+
import { parseLocationConfig } from "./config.js";
|
|
12
|
+
import { startLocationAutoSync } from "./scheduler.js";
|
|
13
|
+
import type { LocationSyncRuns } from "./surfaces.js";
|
|
14
|
+
|
|
15
|
+
function fakeTimer() {
|
|
16
|
+
const armed: Array<{ fn: () => void; unrefd: boolean }> = [];
|
|
17
|
+
const cleared: unknown[] = [];
|
|
18
|
+
return {
|
|
19
|
+
armed,
|
|
20
|
+
cleared,
|
|
21
|
+
setInterval: (fn: () => void, _ms: number) => {
|
|
22
|
+
const handle = { fn, unrefd: false, unref() { this.unrefd = true; } };
|
|
23
|
+
armed.push(handle);
|
|
24
|
+
return handle;
|
|
25
|
+
},
|
|
26
|
+
clearInterval: (handle: unknown) => cleared.push(handle),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const CONFIG = parseLocationConfig({ enabled: true, sources: [{ id: "reitti" }] });
|
|
31
|
+
const RUNS: LocationSyncRuns = [{ date: "2026-08-16", results: [] }];
|
|
32
|
+
|
|
33
|
+
test("start arms one unref'd periodic timer whose tick runs the shared sync", async () => {
|
|
34
|
+
const timer = fakeTimer();
|
|
35
|
+
const syncs: Array<{ config: unknown; memoryDir: string }> = [];
|
|
36
|
+
const infos: string[] = [];
|
|
37
|
+
const handle = startLocationAutoSync(
|
|
38
|
+
{ config: CONFIG, memoryDir: "/tmp/unused-location", setInterval: timer.setInterval, clearInterval: timer.clearInterval },
|
|
39
|
+
{
|
|
40
|
+
sync: async (deps) => {
|
|
41
|
+
syncs.push(deps);
|
|
42
|
+
return RUNS;
|
|
43
|
+
},
|
|
44
|
+
log: { info: (m) => infos.push(m), warn: (m) => infos.push(m) },
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
assert.equal(timer.armed.length, 1);
|
|
48
|
+
assert.equal(timer.armed[0]?.unrefd, true, "one-shot CLI hosts must exit naturally");
|
|
49
|
+
|
|
50
|
+
timer.armed[0]?.fn();
|
|
51
|
+
{ const { promise, resolve } = Promise.withResolvers<void>(); setImmediate(resolve); await promise; }
|
|
52
|
+
assert.equal(syncs.length, 1);
|
|
53
|
+
assert.equal(syncs[0]?.memoryDir, "/tmp/unused-location");
|
|
54
|
+
assert.equal(syncs[0]?.config, CONFIG);
|
|
55
|
+
|
|
56
|
+
// First-run hook: tick() invokes the runner directly.
|
|
57
|
+
await handle.tick();
|
|
58
|
+
assert.equal(syncs.length, 2);
|
|
59
|
+
|
|
60
|
+
await handle.stop();
|
|
61
|
+
assert.equal(timer.cleared.length, 1);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("an overlapping tick is skipped, not queued; failures warn and retry next tick", async () => {
|
|
65
|
+
const timer = fakeTimer();
|
|
66
|
+
let calls = 0;
|
|
67
|
+
let failFirst = true;
|
|
68
|
+
const warns: string[] = [];
|
|
69
|
+
const handle = startLocationAutoSync(
|
|
70
|
+
{ config: CONFIG, memoryDir: "/tmp/unused", setInterval: timer.setInterval, clearInterval: timer.clearInterval },
|
|
71
|
+
{
|
|
72
|
+
sync: async () => {
|
|
73
|
+
calls += 1;
|
|
74
|
+
if (failFirst) {
|
|
75
|
+
failFirst = false;
|
|
76
|
+
throw new Error("ReittiApiError");
|
|
77
|
+
}
|
|
78
|
+
return RUNS;
|
|
79
|
+
},
|
|
80
|
+
log: { info: () => {}, warn: (m) => warns.push(m) },
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
timer.armed[0]?.fn(); // failing tick
|
|
84
|
+
timer.armed[0]?.fn(); // second tick while the first is still in flight
|
|
85
|
+
{ const { promise, resolve } = Promise.withResolvers<void>(); setImmediate(resolve); await promise; }
|
|
86
|
+
assert.equal(calls, 1, "in-flight tick swallows the overlap");
|
|
87
|
+
assert.equal(warns.length, 1);
|
|
88
|
+
assert.match(warns[0] ?? "", /location auto-sync failed: Error/);
|
|
89
|
+
|
|
90
|
+
timer.armed[0]?.fn(); // recovers on the next tick
|
|
91
|
+
{ const { promise, resolve } = Promise.withResolvers<void>(); setImmediate(resolve); await promise; }
|
|
92
|
+
assert.equal(calls, 2);
|
|
93
|
+
|
|
94
|
+
await handle.stop();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("a provider failure surfaces as a warn (per-source failed status), not a throw", async () => {
|
|
98
|
+
const timer = fakeTimer();
|
|
99
|
+
const warns: string[] = [];
|
|
100
|
+
const handle = startLocationAutoSync(
|
|
101
|
+
{ config: CONFIG, memoryDir: "/tmp/unused", setInterval: timer.setInterval, clearInterval: timer.clearInterval },
|
|
102
|
+
{
|
|
103
|
+
sync: async () => [
|
|
104
|
+
{ date: "2026-08-16", results: [{ sourceId: "reitti", status: "failed", fetched: 0, dayWritten: false, stateSaved: false }] },
|
|
105
|
+
],
|
|
106
|
+
log: { info: () => {}, warn: (m) => warns.push(m) },
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
timer.armed[0]?.fn();
|
|
110
|
+
{ const { promise, resolve } = Promise.withResolvers<void>(); setImmediate(resolve); await promise; }
|
|
111
|
+
assert.deepEqual(warns, ["location auto-sync: one or more sources failed — retrying on the next tick"]);
|
|
112
|
+
await handle.stop();
|
|
113
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location auto-sync — in-process periodic day sync (issue #2047).
|
|
3
|
+
*
|
|
4
|
+
* Arms one repeating timer that runs the SAME shared surface runner
|
|
5
|
+
* (`runLocationSync`) as the CLI/MCP/HTTP surfaces over the configured
|
|
6
|
+
* `location.syncDays` window ending yesterday, so late provider uploads are
|
|
7
|
+
* picked up on the next tick. Master default-off: the caller (maintenance
|
|
8
|
+
* scheduler registration) arms this only when `location.enabled` is true and
|
|
9
|
+
* at least one source is enabled; a forced manual sync never bypasses those
|
|
10
|
+
* gates — they live inside the pipeline itself.
|
|
11
|
+
*
|
|
12
|
+
* The timer is unref'd so one-shot CLI processes exit naturally; ticks are
|
|
13
|
+
* serialized (an overlapping tick is skipped, not queued). ponytail: fixed
|
|
14
|
+
* default cadence (daily) with no per-install override — add a
|
|
15
|
+
* location.syncIntervalHours config field if installs need it.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { log } from "../logger.js";
|
|
19
|
+
import { runLocationSync, type LocationSyncRuns } from "./surfaces.js";
|
|
20
|
+
import type { LocationConfig } from "./types.js";
|
|
21
|
+
|
|
22
|
+
export const LOCATION_SYNC_DEFAULT_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
23
|
+
|
|
24
|
+
export interface LocationAutoSyncSettings {
|
|
25
|
+
config: LocationConfig;
|
|
26
|
+
memoryDir: string;
|
|
27
|
+
/** Tick cadence in ms; defaults to LOCATION_SYNC_DEFAULT_INTERVAL_MS. */
|
|
28
|
+
intervalMs?: number;
|
|
29
|
+
/** Clock/timer seam for tests. */
|
|
30
|
+
setInterval?: (fn: () => void, ms: number) => { unref?: () => void };
|
|
31
|
+
clearInterval?: (handle: unknown) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface LocationAutoSyncDeps {
|
|
35
|
+
/** Run a sync (defaults to the shared surface runner). */
|
|
36
|
+
sync?: (deps: { config: LocationConfig; memoryDir: string }) => Promise<LocationSyncRuns>;
|
|
37
|
+
log?: { info(message: string): void; warn(message: string): void };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface LocationAutoSyncHandle {
|
|
41
|
+
/** Run one tick now (first-run hook and test seam). */
|
|
42
|
+
tick(): Promise<void>;
|
|
43
|
+
stop(): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function startLocationAutoSync(
|
|
47
|
+
settings: LocationAutoSyncSettings,
|
|
48
|
+
deps: LocationAutoSyncDeps = {},
|
|
49
|
+
): LocationAutoSyncHandle {
|
|
50
|
+
const logger = deps.log ?? log;
|
|
51
|
+
const intervalMs = settings.intervalMs ?? LOCATION_SYNC_DEFAULT_INTERVAL_MS;
|
|
52
|
+
const setIntervalImpl = settings.setInterval ?? ((fn: () => void, ms: number) => setInterval(fn, ms));
|
|
53
|
+
const clearIntervalImpl = settings.clearInterval ?? ((handle: unknown) => clearInterval(handle as NodeJS.Timeout));
|
|
54
|
+
const sync =
|
|
55
|
+
deps.sync ??
|
|
56
|
+
((deps: { config: LocationConfig; memoryDir: string }) =>
|
|
57
|
+
runLocationSync({ config: deps.config, memoryDir: deps.memoryDir }));
|
|
58
|
+
let inFlight: Promise<void> | null = null;
|
|
59
|
+
let stopped = false;
|
|
60
|
+
const timer = setIntervalImpl(() => {
|
|
61
|
+
if (inFlight !== null || stopped) return;
|
|
62
|
+
inFlight = (async () => {
|
|
63
|
+
try {
|
|
64
|
+
const runs = await sync({ config: settings.config, memoryDir: settings.memoryDir });
|
|
65
|
+
const failed = runs.some((run) => run.results.some((result) => result.status === "failed"));
|
|
66
|
+
if (failed) {
|
|
67
|
+
logger.warn("location auto-sync: one or more sources failed — retrying on the next tick");
|
|
68
|
+
} else {
|
|
69
|
+
logger.info(
|
|
70
|
+
`location auto-sync: refreshed ${settings.config.syncDays}-day window across ${settings.config.sources.length} source(s)`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
// An abort raised by stop() is intentional shutdown, not a failure.
|
|
75
|
+
if (err instanceof Error && err.name === "AbortError") return;
|
|
76
|
+
logger.warn(
|
|
77
|
+
`location auto-sync failed: ${err instanceof Error ? err.name : "unknown error"} — retrying on the next tick`,
|
|
78
|
+
);
|
|
79
|
+
} finally {
|
|
80
|
+
inFlight = null;
|
|
81
|
+
}
|
|
82
|
+
})();
|
|
83
|
+
}, intervalMs);
|
|
84
|
+
timer.unref?.();
|
|
85
|
+
return {
|
|
86
|
+
async tick() {
|
|
87
|
+
const runs = await sync({ config: settings.config, memoryDir: settings.memoryDir });
|
|
88
|
+
logger.info(
|
|
89
|
+
`location auto-sync tick: ${runs.length} day(s) across ${settings.config.sources.length} source(s)`,
|
|
90
|
+
);
|
|
91
|
+
},
|
|
92
|
+
async stop() {
|
|
93
|
+
stopped = true;
|
|
94
|
+
clearIntervalImpl(timer);
|
|
95
|
+
await inFlight;
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location surfaces regression (issue #2047): one shared runner behind the
|
|
3
|
+
* CLI / MCP / HTTP / scheduler surfaces. These tests pin the contract the
|
|
4
|
+
* issue requires — disabled vs empty vs failure are distinct, validation is
|
|
5
|
+
* identical across surfaces, and provider registration bootstraps before
|
|
6
|
+
* status/check/sync run.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import assert from "node:assert/strict";
|
|
10
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import test from "node:test";
|
|
14
|
+
|
|
15
|
+
import { parseLocationConfig } from "./config.js";
|
|
16
|
+
import {
|
|
17
|
+
clearLocationProviders,
|
|
18
|
+
registerLocationProvider,
|
|
19
|
+
} from "./registry.js";
|
|
20
|
+
import { parseLocationBackfillRange, runLocationCliCommand } from "./surfaces.js";
|
|
21
|
+
import type { LocationProvider } from "./types.js";
|
|
22
|
+
|
|
23
|
+
function io() {
|
|
24
|
+
const stdout: string[] = [];
|
|
25
|
+
const stderr: string[] = [];
|
|
26
|
+
return {
|
|
27
|
+
stdout,
|
|
28
|
+
stderr,
|
|
29
|
+
cliIo: {
|
|
30
|
+
stdout: { write: (chunk: string) => stdout.push(chunk) },
|
|
31
|
+
stderr: { write: (chunk: string) => stderr.push(chunk) },
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const OBSERVATION = {
|
|
37
|
+
observedAtUtc: "2026-08-16T09:00:00.000Z",
|
|
38
|
+
place: { id: "reitti:place:1", label: "Home" },
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** Observations only for the 2026-08-16 window; other days are valid empty days. */
|
|
42
|
+
function fakeProvider(): LocationProvider {
|
|
43
|
+
return {
|
|
44
|
+
id: "reitti",
|
|
45
|
+
displayName: "Reitti",
|
|
46
|
+
verify: async () => ({ ok: true }),
|
|
47
|
+
fetchObservations: async (opts) => {
|
|
48
|
+
assert.ok(opts.startUtc < opts.endUtc, "window must be half-open");
|
|
49
|
+
const inWindow = opts.startUtc.startsWith("2026-08-16");
|
|
50
|
+
return {
|
|
51
|
+
observations: inWindow
|
|
52
|
+
? [{ observedAtUtc: OBSERVATION.observedAtUtc, place: { ...OBSERVATION.place, kind: "other" as const } }]
|
|
53
|
+
: [],
|
|
54
|
+
nextCursor: null,
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function enabledConfig() {
|
|
61
|
+
return parseLocationConfig({
|
|
62
|
+
enabled: true,
|
|
63
|
+
timezone: "UTC",
|
|
64
|
+
syncDays: 1,
|
|
65
|
+
sources: [{ id: "reitti" }],
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
test.afterEach(() => clearLocationProviders());
|
|
70
|
+
|
|
71
|
+
test("status reports disabled master gate and unregistered provider, never an error", async () => {
|
|
72
|
+
const config = parseLocationConfig({ enabled: false, sources: [{ id: "reitti" }] });
|
|
73
|
+
const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-location-status-"));
|
|
74
|
+
try {
|
|
75
|
+
const out = io();
|
|
76
|
+
const code = await runLocationCliCommand({ config, memoryDir }, ["status", "--json"], out.cliIo);
|
|
77
|
+
assert.equal(code, 0);
|
|
78
|
+
const report = JSON.parse(out.stdout.join("")) as { enabled: boolean; sources: Array<{ providerRegistered: boolean }> };
|
|
79
|
+
assert.equal(report.enabled, false);
|
|
80
|
+
assert.equal(report.sources[0]?.providerRegistered, false, "absent provider is a skip state, not an error");
|
|
81
|
+
} finally {
|
|
82
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("check distinguishes skip reasons from provider failures", async () => {
|
|
87
|
+
const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-location-check-"));
|
|
88
|
+
try {
|
|
89
|
+
// Master gate off → location-disabled skip, exit non-zero.
|
|
90
|
+
const disabled = io();
|
|
91
|
+
const disabledCode = await runLocationCliCommand(
|
|
92
|
+
{ config: parseLocationConfig({ enabled: false, sources: [{ id: "reitti" }] }), memoryDir },
|
|
93
|
+
["check"],
|
|
94
|
+
disabled.cliIo,
|
|
95
|
+
);
|
|
96
|
+
assert.match(disabled.stdout.join(""), /skipped: location-disabled/);
|
|
97
|
+
assert.equal(disabledCode, 1);
|
|
98
|
+
|
|
99
|
+
// Enabled but provider absent → provider-not-registered, distinct reason.
|
|
100
|
+
const unregistered = io();
|
|
101
|
+
const unregisteredCode = await runLocationCliCommand({ config: enabledConfig(), memoryDir }, ["check"], unregistered.cliIo);
|
|
102
|
+
assert.match(unregistered.stdout.join(""), /skipped: provider-not-registered/);
|
|
103
|
+
assert.equal(unregisteredCode, 1);
|
|
104
|
+
|
|
105
|
+
// Registered healthy provider → OK, exit 0.
|
|
106
|
+
registerLocationProvider(fakeProvider());
|
|
107
|
+
const healthy = io();
|
|
108
|
+
const healthyCode = await runLocationCliCommand({ config: enabledConfig(), memoryDir }, ["check"], healthy.cliIo);
|
|
109
|
+
assert.match(healthy.stdout.join(""), /reitti: OK/);
|
|
110
|
+
assert.equal(healthyCode, 0);
|
|
111
|
+
} finally {
|
|
112
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("sync writes the day file through the shared runner and reports per-source results", async () => {
|
|
117
|
+
registerLocationProvider(fakeProvider());
|
|
118
|
+
const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-location-sync-"));
|
|
119
|
+
try {
|
|
120
|
+
const out = io();
|
|
121
|
+
const code = await runLocationCliCommand(
|
|
122
|
+
{ config: enabledConfig(), memoryDir },
|
|
123
|
+
["sync", "--date", "2026-08-16", "--json"],
|
|
124
|
+
out.cliIo,
|
|
125
|
+
);
|
|
126
|
+
assert.equal(code, 0);
|
|
127
|
+
const payload = JSON.parse(out.stdout.join("")) as {
|
|
128
|
+
days: Array<{ date: string; results: Array<{ sourceId: string; status: string; fetched: number; dayWritten: boolean }> }>;
|
|
129
|
+
};
|
|
130
|
+
assert.equal(payload.days.length, 1);
|
|
131
|
+
assert.equal(payload.days[0]?.date, "2026-08-16");
|
|
132
|
+
assert.equal(payload.days[0]?.results[0]?.status, "synced");
|
|
133
|
+
assert.equal(payload.days[0]?.results[0]?.dayWritten, true);
|
|
134
|
+
|
|
135
|
+
// day reads back what sync wrote (same shared implementation).
|
|
136
|
+
const dayOut = io();
|
|
137
|
+
const dayCode = await runLocationCliCommand({ config: enabledConfig(), memoryDir }, ["day", "2026-08-16", "--json"], dayOut.cliIo);
|
|
138
|
+
assert.equal(dayCode, 0);
|
|
139
|
+
const view = JSON.parse(dayOut.stdout.join("")) as { found: boolean; observationCount: number; sources: string[] };
|
|
140
|
+
assert.equal(view.found, true);
|
|
141
|
+
assert.equal(view.observationCount, 1, "one stored observation from the fake provider");
|
|
142
|
+
assert.deepEqual(view.sources, ["reitti"]);
|
|
143
|
+
|
|
144
|
+
// An unstored day is an explicit not-found, not an error.
|
|
145
|
+
const missing = io();
|
|
146
|
+
const missingCode = await runLocationCliCommand({ config: enabledConfig(), memoryDir }, ["day", "2026-01-01"], missing.cliIo);
|
|
147
|
+
assert.equal(missingCode, 1);
|
|
148
|
+
assert.match(missing.stderr.join(""), /No stored location day/);
|
|
149
|
+
} finally {
|
|
150
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test("sync exit code reflects per-source failure", async () => {
|
|
155
|
+
const provider: LocationProvider = {
|
|
156
|
+
id: "reitti",
|
|
157
|
+
displayName: "Reitti",
|
|
158
|
+
verify: async () => ({ ok: true }),
|
|
159
|
+
fetchObservations: async () => {
|
|
160
|
+
throw new Error("ReittiApiError");
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
registerLocationProvider(provider);
|
|
164
|
+
const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-location-fail-"));
|
|
165
|
+
try {
|
|
166
|
+
const out = io();
|
|
167
|
+
const code = await runLocationCliCommand({ config: enabledConfig(), memoryDir }, ["sync", "--date", "2026-08-16"], out.cliIo);
|
|
168
|
+
assert.equal(code, 1);
|
|
169
|
+
assert.match(out.stdout.join(""), /reitti: failed/);
|
|
170
|
+
} finally {
|
|
171
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test("validation is strict and shared: unknown flags, bad dates, bad ranges", async () => {
|
|
176
|
+
const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-location-args-"));
|
|
177
|
+
try {
|
|
178
|
+
const cases: Array<[string[], RegExp]> = [
|
|
179
|
+
[["sync", "--nope"], /unknown flag '--nope'/],
|
|
180
|
+
[["sync", "--days"], /--days requires a value/],
|
|
181
|
+
[["sync", "--days", "0"], /days expects an integer from 1 to 90/],
|
|
182
|
+
[["sync", "--date", "2026-13-99"], /date is required \(YYYY-MM-DD\)/],
|
|
183
|
+
[["day", "not-a-date"], /date is required \(YYYY-MM-DD\)/],
|
|
184
|
+
[["backfill", "--from", "2026-08-10", "--to", "2026-08-01"], /--from must not be after --to/],
|
|
185
|
+
[["sync", "positional"], /sync takes flags only/],
|
|
186
|
+
[["nonsense"], /unknown command 'nonsense'/],
|
|
187
|
+
];
|
|
188
|
+
for (const [args, pattern] of cases) {
|
|
189
|
+
const out = io();
|
|
190
|
+
const code = await runLocationCliCommand({ config: enabledConfig(), memoryDir }, args, out.cliIo);
|
|
191
|
+
assert.equal(code, 1, `${JSON.stringify(args)} exits non-zero`);
|
|
192
|
+
assert.match(out.stderr.join(""), pattern);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Backfill range cap: 91 days rejects; 90 passes.
|
|
196
|
+
assert.throws(() => parseLocationBackfillRange("2026-05-01", "2026-07-30"), /capped at 90 days/);
|
|
197
|
+
assert.deepEqual(parseLocationBackfillRange("2026-05-02", "2026-07-30"), { endDate: "2026-07-30", days: 90 });
|
|
198
|
+
} finally {
|
|
199
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("backfill syncs the explicit range oldest-first; empty days are synced, not failed", async () => {
|
|
204
|
+
registerLocationProvider(fakeProvider());
|
|
205
|
+
const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-location-backfill-"));
|
|
206
|
+
try {
|
|
207
|
+
const out = io();
|
|
208
|
+
const code = await runLocationCliCommand(
|
|
209
|
+
{ config: enabledConfig(), memoryDir },
|
|
210
|
+
["backfill", "--from", "2026-08-14", "--to", "2026-08-16", "--json"],
|
|
211
|
+
out.cliIo,
|
|
212
|
+
);
|
|
213
|
+
assert.equal(code, 0);
|
|
214
|
+
const payload = JSON.parse(out.stdout.join("")) as { days: Array<{ date: string; results: Array<{ status: string; fetched: number }> }> };
|
|
215
|
+
assert.deepEqual(
|
|
216
|
+
payload.days.map((d) => d.date),
|
|
217
|
+
["2026-08-14", "2026-08-15", "2026-08-16"],
|
|
218
|
+
"oldest-first bounded range",
|
|
219
|
+
);
|
|
220
|
+
assert.deepEqual(
|
|
221
|
+
payload.days.map((d) => d.results[0]?.status),
|
|
222
|
+
["synced", "synced", "synced"],
|
|
223
|
+
"empty days are synced, not failed",
|
|
224
|
+
);
|
|
225
|
+
} finally {
|
|
226
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
test("bare command prints usage with exit 1; help exits 0", async () => {
|
|
231
|
+
const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-location-help-"));
|
|
232
|
+
try {
|
|
233
|
+
const bare = io();
|
|
234
|
+
assert.equal(await runLocationCliCommand({ config: enabledConfig(), memoryDir }, [], bare.cliIo), 1);
|
|
235
|
+
assert.match(bare.stdout.join(""), /Usage: location/);
|
|
236
|
+
const help = io();
|
|
237
|
+
assert.equal(await runLocationCliCommand({ config: enabledConfig(), memoryDir }, ["help"], help.cliIo), 0);
|
|
238
|
+
} finally {
|
|
239
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
240
|
+
}
|
|
241
|
+
});
|