@remnic/core 9.45.0 → 9.45.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +10 -10
- package/dist/access-admin-ops-surface.js +25 -25
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +10 -10
- package/dist/access-authorization-probe.js +26 -26
- package/dist/access-boundary.d.ts +10 -10
- package/dist/access-boundary.js +25 -25
- package/dist/access-cli.js +69 -68
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.d.ts +10 -10
- package/dist/access-extraction-force-flush.js +25 -25
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +10 -10
- package/dist/access-http-lifecycle-flush.d.ts +10 -10
- package/dist/access-http-query.js +25 -25
- package/dist/access-http.d.ts +10 -10
- package/dist/access-http.js +34 -34
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +25 -25
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +25 -25
- package/dist/access-mcp.d.ts +10 -10
- package/dist/access-mcp.js +30 -30
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-47dOyty9.d.ts → access-namespace-preflight-5yZ4g6F8.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +25 -25
- package/dist/access-observe-write-surface.d.ts +10 -10
- package/dist/access-observe-write-surface.js +25 -25
- package/dist/access-operations-batch.js +27 -27
- package/dist/access-operations.d.ts +10 -10
- package/dist/access-operations.js +29 -29
- package/dist/access-recall-concurrency.d.ts +10 -10
- package/dist/access-recall-concurrency.js +25 -25
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +25 -25
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +25 -25
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-DBo88Dmm.d.ts → access-service-CiJRsgAB.d.ts} +7 -7
- package/dist/access-service-helpers.d.ts +10 -10
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +25 -25
- package/dist/access-surface-catalog.d.ts +10 -10
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +3 -2
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +8 -8
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +8 -8
- 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/{catalog-DPQynQZG.d.ts → catalog-scBmy0sO.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 +11 -11
- 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-GBJJUPNV.js → chunk-33PLLLL7.js} +2 -2
- package/dist/{chunk-ZAB5PG65.js → chunk-3F2LKUMU.js} +2 -2
- package/dist/{chunk-TXBU7YDV.js → chunk-3TBLDMJA.js} +2 -2
- package/dist/{chunk-6UWB5PTR.js → chunk-4L6HUREQ.js} +54 -24
- package/dist/chunk-4L6HUREQ.js.map +1 -0
- package/dist/{chunk-FLBPATMZ.js → chunk-4UH4BTGK.js} +33 -33
- package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
- package/dist/{chunk-K6OTW3TP.js → chunk-A5OJCXZL.js} +2 -2
- package/dist/{chunk-QQ3NDJOM.js → chunk-AAIUERNB.js} +2 -2
- package/dist/{chunk-C7EI7CA6.js → chunk-BJKPPZ6Z.js} +2 -2
- package/dist/{chunk-65V4K4MT.js → chunk-CJ2ZR7UA.js} +17 -17
- package/dist/{chunk-TM72UOX2.js → chunk-CUM2BBPN.js} +5 -1
- package/dist/chunk-CUM2BBPN.js.map +1 -0
- package/dist/{chunk-GQBZ7EVF.js → chunk-D3J5SLQK.js} +2 -2
- package/dist/{chunk-3HLCRYBV.js → chunk-DL7ZD3JH.js} +3 -3
- package/dist/{chunk-ZPJJE7MF.js → chunk-DNWXFTLD.js} +2 -2
- package/dist/{chunk-YQQK7W7T.js → chunk-E53DSZEN.js} +2 -2
- package/dist/{chunk-6OLQJJYE.js → chunk-E5UK4VPE.js} +2 -2
- package/dist/{chunk-3HKQOFOV.js → chunk-E6PNLPGJ.js} +19 -19
- package/dist/{chunk-Z54EM5YZ.js → chunk-GF22HWS2.js} +4 -4
- package/dist/chunk-HBVPYRDW.js +39 -0
- package/dist/chunk-HBVPYRDW.js.map +1 -0
- package/dist/{chunk-W6ROK2KU.js → chunk-HNZKVLAN.js} +2 -2
- package/dist/{chunk-GDC4INBF.js → chunk-HO3QBJEY.js} +2 -2
- package/dist/{chunk-U5G66ORD.js → chunk-HREE4JHI.js} +48 -48
- package/dist/{chunk-GSL47NPM.js → chunk-J7VGGECD.js} +1 -1
- package/dist/chunk-J7VGGECD.js.map +1 -0
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/{chunk-7PVFOFPJ.js → chunk-JE7EK33X.js} +2 -2
- package/dist/{chunk-WG2PI44B.js → chunk-JVLCVFQ4.js} +2 -2
- package/dist/{chunk-UZGJFIIG.js → chunk-JYIFGGEM.js} +2 -2
- package/dist/{chunk-IPLYGWQF.js → chunk-KQAFEZQX.js} +5 -5
- package/dist/{chunk-3SHB4YAW.js → chunk-L2DPF4DF.js} +4 -4
- package/dist/{chunk-VRYJSKOM.js → chunk-LZ4LDKHZ.js} +2 -2
- package/dist/{chunk-PO5LSKQO.js → chunk-MU7ZHSZE.js} +2 -2
- package/dist/{chunk-CAGPP5NB.js → chunk-NRV4Y3PM.js} +1 -1
- package/dist/{chunk-SS7YWVPF.js → chunk-OAEQLRCY.js} +2 -2
- package/dist/{chunk-FVGQ5LIS.js → chunk-OQ5PRDDS.js} +2 -2
- package/dist/{chunk-5YGO5VEH.js → chunk-P4DRWEYC.js} +2 -2
- package/dist/{chunk-XMZV27S5.js → chunk-PDLBLTOK.js} +2 -2
- package/dist/{chunk-VCGPO2VD.js → chunk-PKNLM44P.js} +4 -4
- package/dist/{chunk-XFQRFWVS.js → chunk-QN25OCUF.js} +2 -2
- package/dist/{chunk-J4OKD6QX.js → chunk-RN7DY3FC.js} +5 -5
- package/dist/{chunk-7JO6RVBI.js → chunk-S2NCTZGJ.js} +4 -4
- package/dist/{chunk-R4Q7CQGZ.js → chunk-TDHTVMPG.js} +2 -2
- package/dist/{chunk-FXGLFGIG.js → chunk-TIHMZFIV.js} +3 -3
- package/dist/{chunk-ZS5UZU5M.js → chunk-U7GW7NE7.js} +7 -7
- package/dist/{chunk-WC4SPYHX.js → chunk-UVIKWC7M.js} +10 -10
- package/dist/{chunk-2QR2RRH6.js → chunk-UYLMNVY6.js} +4 -4
- package/dist/{chunk-G24XIK6H.js → chunk-VUPTKTDV.js} +2 -2
- package/dist/{chunk-GOPWZYZH.js → chunk-VWAXN2BN.js} +8 -8
- package/dist/{chunk-JZ7SSAQ5.js → chunk-XYTOI63Z.js} +3 -3
- package/dist/{cli-DQ4VhjqX.d.ts → cli-BUGN3d6_.d.ts} +5 -5
- package/dist/cli.d.ts +12 -12
- package/dist/cli.js +52 -51
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +8 -8
- 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 +3 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +8 -8
- 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 +2 -2
- package/dist/converge-config.d.ts +11 -0
- package/dist/converge-config.js +12 -0
- 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/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +8 -8
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +8 -8
- 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-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +10 -10
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/{graph-edge-decay-GF3ZSGSP.js → graph-edge-decay-Z6ENALU2.js} +4 -4
- package/dist/graph-edge-decay-Z6ENALU2.js.map +1 -0
- package/dist/graph-edge-reinforcement.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 +2 -2
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/index.d.ts +20 -19
- package/dist/index.js +77 -71
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +4 -4
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +8 -8
- 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-_RV38GlE.d.ts → maintenance-LbuS2rUA.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +10 -10
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-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 +9 -9
- 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 +8 -8
- 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 +11 -11
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +19 -18
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +13 -13
- package/dist/{orchestrator-B2ecFpRO.d.ts → orchestrator-rHiWt32X.d.ts} +7 -7
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +69 -68
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-Cs76XC-p.d.ts → pipeline-W_97O8BV.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{qmd-WJwvBgiF.d.ts → qmd-LWtMofAf.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/recall-concurrency-config.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +11 -1
- package/dist/reconcile/cursor.js +54 -0
- package/dist/reconcile/cursor.js.map +1 -1
- package/dist/reconcile/manifest.d.ts +3 -3
- package/dist/reconcile/manifest.js +42 -4
- package/dist/reconcile/manifest.js.map +1 -1
- package/dist/reconcile/plan.d.ts +32 -21
- package/dist/reconcile/plan.js +2 -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 +4 -3
- 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-CQ0NAleS.d.ts → scope-profiles-BiQKOE-p.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-BWxOBMtz.d.ts → semantic-consolidation-dHYCyqgh.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +9 -9
- package/dist/semantic-rule-promotion.js +8 -8
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +8 -8
- package/dist/{service-DW06sY3P.d.ts → service-DJG3KCQ4.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 +8 -8
- package/dist/{storage-qRIQPA6F.d.ts → storage-F9FVh-w9.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +7 -7
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +1 -1
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-CqWwMPr_.d.ts → types-rEwubvim.d.ts} +6 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +8 -8
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/config.test.ts +24 -0
- package/src/config.ts +3 -0
- package/src/converge-config.ts +39 -0
- package/src/index.ts +1 -2
- package/src/reconcile/cursor.test.ts +30 -0
- package/src/reconcile/cursor.ts +63 -0
- package/src/reconcile/manifest.test.ts +93 -2
- package/src/reconcile/manifest.ts +56 -3
- package/src/reconcile/plan.test.ts +40 -52
- package/src/reconcile/plan.ts +95 -61
- package/src/types.ts +5 -0
- package/dist/chunk-6UWB5PTR.js.map +0 -1
- package/dist/chunk-GSL47NPM.js.map +0 -1
- package/dist/chunk-TM72UOX2.js.map +0 -1
- /package/dist/{chunk-GBJJUPNV.js.map → chunk-33PLLLL7.js.map} +0 -0
- /package/dist/{chunk-ZAB5PG65.js.map → chunk-3F2LKUMU.js.map} +0 -0
- /package/dist/{chunk-TXBU7YDV.js.map → chunk-3TBLDMJA.js.map} +0 -0
- /package/dist/{chunk-FLBPATMZ.js.map → chunk-4UH4BTGK.js.map} +0 -0
- /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
- /package/dist/{chunk-K6OTW3TP.js.map → chunk-A5OJCXZL.js.map} +0 -0
- /package/dist/{chunk-QQ3NDJOM.js.map → chunk-AAIUERNB.js.map} +0 -0
- /package/dist/{chunk-C7EI7CA6.js.map → chunk-BJKPPZ6Z.js.map} +0 -0
- /package/dist/{chunk-65V4K4MT.js.map → chunk-CJ2ZR7UA.js.map} +0 -0
- /package/dist/{chunk-GQBZ7EVF.js.map → chunk-D3J5SLQK.js.map} +0 -0
- /package/dist/{chunk-3HLCRYBV.js.map → chunk-DL7ZD3JH.js.map} +0 -0
- /package/dist/{chunk-ZPJJE7MF.js.map → chunk-DNWXFTLD.js.map} +0 -0
- /package/dist/{chunk-YQQK7W7T.js.map → chunk-E53DSZEN.js.map} +0 -0
- /package/dist/{chunk-6OLQJJYE.js.map → chunk-E5UK4VPE.js.map} +0 -0
- /package/dist/{chunk-3HKQOFOV.js.map → chunk-E6PNLPGJ.js.map} +0 -0
- /package/dist/{chunk-Z54EM5YZ.js.map → chunk-GF22HWS2.js.map} +0 -0
- /package/dist/{chunk-W6ROK2KU.js.map → chunk-HNZKVLAN.js.map} +0 -0
- /package/dist/{chunk-GDC4INBF.js.map → chunk-HO3QBJEY.js.map} +0 -0
- /package/dist/{chunk-U5G66ORD.js.map → chunk-HREE4JHI.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-7PVFOFPJ.js.map → chunk-JE7EK33X.js.map} +0 -0
- /package/dist/{chunk-WG2PI44B.js.map → chunk-JVLCVFQ4.js.map} +0 -0
- /package/dist/{chunk-UZGJFIIG.js.map → chunk-JYIFGGEM.js.map} +0 -0
- /package/dist/{chunk-IPLYGWQF.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-3SHB4YAW.js.map → chunk-L2DPF4DF.js.map} +0 -0
- /package/dist/{chunk-VRYJSKOM.js.map → chunk-LZ4LDKHZ.js.map} +0 -0
- /package/dist/{chunk-PO5LSKQO.js.map → chunk-MU7ZHSZE.js.map} +0 -0
- /package/dist/{chunk-CAGPP5NB.js.map → chunk-NRV4Y3PM.js.map} +0 -0
- /package/dist/{chunk-SS7YWVPF.js.map → chunk-OAEQLRCY.js.map} +0 -0
- /package/dist/{chunk-FVGQ5LIS.js.map → chunk-OQ5PRDDS.js.map} +0 -0
- /package/dist/{chunk-5YGO5VEH.js.map → chunk-P4DRWEYC.js.map} +0 -0
- /package/dist/{chunk-XMZV27S5.js.map → chunk-PDLBLTOK.js.map} +0 -0
- /package/dist/{chunk-VCGPO2VD.js.map → chunk-PKNLM44P.js.map} +0 -0
- /package/dist/{chunk-XFQRFWVS.js.map → chunk-QN25OCUF.js.map} +0 -0
- /package/dist/{chunk-J4OKD6QX.js.map → chunk-RN7DY3FC.js.map} +0 -0
- /package/dist/{chunk-7JO6RVBI.js.map → chunk-S2NCTZGJ.js.map} +0 -0
- /package/dist/{chunk-R4Q7CQGZ.js.map → chunk-TDHTVMPG.js.map} +0 -0
- /package/dist/{chunk-FXGLFGIG.js.map → chunk-TIHMZFIV.js.map} +0 -0
- /package/dist/{chunk-ZS5UZU5M.js.map → chunk-U7GW7NE7.js.map} +0 -0
- /package/dist/{chunk-WC4SPYHX.js.map → chunk-UVIKWC7M.js.map} +0 -0
- /package/dist/{chunk-2QR2RRH6.js.map → chunk-UYLMNVY6.js.map} +0 -0
- /package/dist/{chunk-G24XIK6H.js.map → chunk-VUPTKTDV.js.map} +0 -0
- /package/dist/{chunk-GOPWZYZH.js.map → chunk-VWAXN2BN.js.map} +0 -0
- /package/dist/{chunk-JZ7SSAQ5.js.map → chunk-XYTOI63Z.js.map} +0 -0
- /package/dist/{graph-edge-decay-GF3ZSGSP.js.map → converge-config.js.map} +0 -0
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { aU as AccessTrackingEntry, a1 as ActiveRecallChatType, a5 as ActiveRecallModelFallbackPolicy, a3 as ActiveRecallPromptStyle, a2 as ActiveRecallQueryMode, a4 as ActiveRecallThinking, t as AgentAccessAuthToken, cq as AgentAccessHttpConfig, cr as AgentDefaultsConfig, cs as AgentPersona, A as AgentPersonaModelConfig, ct as BehaviorLoopAdjustment, r as BehaviorLoopPolicyState, cu as BehaviorSignalDirection, a6 as BehaviorSignalEvent, cv as BehaviorSignalType, bd as BootstrapOptions, be as BootstrapResult, g as BriefingActiveThread, cw as BriefingCalendarSourceError, by as BriefingConfig, e as BriefingFocus, d as BriefingFollowup, bz as BriefingOpenCommitment, i as BriefingRecentEntity, h as BriefingResult, B as BriefingSections, bA as BriefingWindow, cx as BufferEntryState, aQ as BufferState, a7 as BufferSurpriseEvent, j as BufferTurn, f as CalendarEvent, C as CalendarSource, w as CaptureMode, cy as ChatConfig, m as Checkpoint, cz as CodexCliReasoningEffort, cA as CodexCompactionFlushMode, bD as CodexCompatConfig, cB as CodexConnectorConfig, ba as CodingContext, cC as CodingGraphLspConfig, bm as CodingKnowledgeConfig, bg as CodingModeConfig, cD as CompressionGuidelineActivationState, ad as CompressionGuidelineOptimizerActionSummary, ac as CompressionGuidelineOptimizerEventCounts, ae as CompressionGuidelineOptimizerRuleUpdate, cE as CompressionGuidelineOptimizerSourceWindow, ah as CompressionGuidelineOptimizerState, cF as ConfidenceTier, cG as ConsolidationAction, cH as ConsolidationItem, bf as ConsolidationObservation, K as ConsolidationResult, cI as ContradictionScanConfig, aj as ConvergeConfig, ai as ConvergeConflictPolicy, V as ConversationThread, cJ as CronConversationRecallMode, cK as CronRecallMode, bE as DEFAULT_RECALL_DISCLOSURE, N as DaySummaryResult, cL as DreamingConfig, cM as DreamingNarrativePromptStyle, cN as DreamsDeepSleepConfig, cO as DreamsLightSleepConfig, D as DreamsPhase, cP as DreamsPhaseStatus, cQ as DreamsPhasesConfig, cR as DreamsRemConfig, a as DreamsRunResult, bb as DreamsStatusResult, cS as EngramTraceEvent, aT as EntityActivityEntry, E as EntityFile, ak as EntityMention, aS as EntityRelationship, al as EntitySchemaDefinition, am as EntitySchemaSectionDefinition, an as EntityStructuredSection, aO as EntityTimelineEntry, bG as ExtractedFact, cT as ExtractedProcedureStep, cU as ExtractedQuestion, cV as ExtractedReasoningTrace, cW as ExtractedReasoningTraceStep, cX as ExtractedRelationship, $ as ExtractionFailureClass, cY as ExtractionPassSource, J as ExtractionResult, F as FaithfulnessFrontmatter, aR as FileHygieneConfig, G as GatewayConfig, cZ as GitHubLiveConnectorConfig, c_ as GmailLiveConnectorConfig, c$ as GoogleDriveLiveConnectorConfig, d0 as HeartbeatConfig, d1 as HeartbeatDetectionMode, H as HourlySummary, I as IdentityInjectionMode, a0 as ImportanceLevel, ap as ImportanceScore, W as LifecycleState, L as LiveConnectorsConfig, d2 as LlmTraceCallback, d3 as LlmTraceEvent, ar as MemoryActionEligibilityContext, bP as MemoryActionEligibilitySource, ag as MemoryActionEvent, d4 as MemoryActionOutcome, d5 as MemoryActionPolicyDecision, as as MemoryActionPolicyResult, d6 as MemoryActionStatus, af as MemoryActionType, v as MemoryCategory, M as MemoryFile, l as MemoryFrontmatter, aq as MemoryIntent, z as MemoryLifecycleEvent, at as MemoryLifecycleEventType, au as MemoryLifecycleStateSummary, aP as MemoryLink, d7 as MemoryLinkType, bQ as MemoryObservation, d8 as MemoryOsPresetName, y as MemoryProjectionCurrentState, bR as MemoryScope, x as MemoryStatus, aV as MemorySummary, ay as MetaState, d9 as ModelApi, da as ModelDefinitionConfig, db as ModelProviderAuthMode, av as ModelProviderConfig, dc as NamespacePolicy, aw as NativeKnowledgeConfig, dd as NativeKnowledgeFolderRuleConfig, de as NativeKnowledgeObsidianVaultConfig, df as NativeKnowledgeOpenClawWorkspaceConfig, dg as NotionLiveConnectorConfig, P as PluginConfig, Y as PolicyClass, dh as PrincipalFromSessionKeyMode, di as PrincipalRule, dj as ProceduralConfig, ao as ProvenanceConfig, O as ProvenanceSource, aD as QmdSearchExplain, Q as QmdSearchResult, dk as QuestionEntry, bS as RECALL_DISCLOSURE_LEVELS, dl as ReasoningEffort, b as RecallDisclosure, dm as RecallPipelineConfig, R as RecallPlanMode, bc as RecallSectionConfig, c as RecallTierExplain, dn as RecallTraceEvent, dp as RelevanceFeedback, aA as RetrievalTier, dq as SPECULATIVE_TTL_DAYS, dr as ScopeProfileAutoPromoteConfig, o as ScopeProfileConfig, p as ScopeProfileLayerId, q as ScopeProfilePromotionTarget, ds as ScopeProfileTeamProjectConfig, dt as ScopeTeamConfig, du as ScoredEntity, s as SecretRef, dv as SemanticChunkingConfigShape, S as SessionObserverBandConfig, dw as SignalLevel, aB as SignalScanResult, dx as SlotBehaviorConfig, dy as SlotMismatchMode, n as SourceConnectorProvenance, aC as TopicScore, T as TranscriptEntry, dz as TriggerMode, U as TrustWeights, X as VerificationState, dA as confidenceTier, b_ as isRecallDisclosure } from './types-rEwubvim.js';
|
|
2
2
|
import './message-parts/index.js';
|
|
3
3
|
import './bounded-jsonl-state.js';
|
|
4
4
|
export { ContinuityImprovementLoop, ContinuityIncidentCloseInput, ContinuityIncidentOpenInput, ContinuityIncidentRecord, ContinuityIncidentState, ContinuityLoopCadence, ContinuityLoopReviewInput, ContinuityLoopStatus, ContinuityLoopUpsertInput } from './types-continuity.js';
|
package/dist/types.js
CHANGED
package/dist/verified-recall.js
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
compareVerifiedEpisodeResults,
|
|
3
3
|
searchVerifiedEpisodes
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OQ5PRDDS.js";
|
|
5
5
|
import "./chunk-B7RWBZXW.js";
|
|
6
6
|
import "./chunk-ZBJMUXZH.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-ENTCVTQR.js";
|
|
7
|
+
import "./chunk-E6PNLPGJ.js";
|
|
9
8
|
import "./chunk-UHVXE24Y.js";
|
|
9
|
+
import "./chunk-ENTCVTQR.js";
|
|
10
10
|
import "./chunk-WIPEXG6R.js";
|
|
11
11
|
import "./chunk-J6A3CX5N.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-J7VGGECD.js";
|
|
13
13
|
import "./chunk-WUNIWKY4.js";
|
|
14
14
|
import "./chunk-EGGE52UU.js";
|
|
15
15
|
import "./chunk-ZA53AZND.js";
|
|
16
|
+
import "./chunk-SCU65EZI.js";
|
|
16
17
|
import "./chunk-WRJVB3C2.js";
|
|
17
18
|
import "./chunk-GCASGYIO.js";
|
|
18
19
|
import "./chunk-7RJUVTVF.js";
|
|
19
|
-
import "./chunk-SCU65EZI.js";
|
|
20
20
|
import "./chunk-DM2T26WE.js";
|
|
21
21
|
import "./chunk-LDXUBPMO.js";
|
|
22
|
+
import "./chunk-JYIJNNN3.js";
|
|
23
|
+
import "./chunk-AAD2ZS6P.js";
|
|
22
24
|
import "./chunk-RVLJEII5.js";
|
|
23
25
|
import "./chunk-S5SLVSVY.js";
|
|
24
26
|
import "./chunk-CGASUJVP.js";
|
|
@@ -26,8 +28,6 @@ import "./chunk-R3DJVOSM.js";
|
|
|
26
28
|
import "./chunk-BT7NVCML.js";
|
|
27
29
|
import "./chunk-3CSX3ETE.js";
|
|
28
30
|
import "./chunk-RL6NEVXT.js";
|
|
29
|
-
import "./chunk-JYIJNNN3.js";
|
|
30
|
-
import "./chunk-AAD2ZS6P.js";
|
|
31
31
|
import "./chunk-YXZG5TVN.js";
|
|
32
32
|
import "./chunk-W5H6ZRPT.js";
|
|
33
33
|
import "./chunk-G7D6GZ5J.js";
|
|
@@ -47,8 +47,8 @@ import "./chunk-45GF7Y3V.js";
|
|
|
47
47
|
import "./chunk-RGMVMVMF.js";
|
|
48
48
|
import "./chunk-N7RWREIQ.js";
|
|
49
49
|
import "./chunk-5I4M26Q7.js";
|
|
50
|
-
import "./chunk-5GKPFL3S.js";
|
|
51
50
|
import "./chunk-ZIKENA2C.js";
|
|
51
|
+
import "./chunk-5GKPFL3S.js";
|
|
52
52
|
import "./chunk-PQVCH2AE.js";
|
|
53
53
|
import "./chunk-EYIEWJNI.js";
|
|
54
54
|
import "./chunk-JUC24CTX.js";
|
package/dist/write-envelope.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/core",
|
|
3
|
-
"version": "9.45.
|
|
3
|
+
"version": "9.45.2",
|
|
4
4
|
"description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -3106,7 +3106,7 @@
|
|
|
3106
3106
|
"core"
|
|
3107
3107
|
],
|
|
3108
3108
|
"peerDependencies": {
|
|
3109
|
-
"@remnic/coding-graph": "^9.45.
|
|
3109
|
+
"@remnic/coding-graph": "^9.45.2"
|
|
3110
3110
|
},
|
|
3111
3111
|
"peerDependenciesMeta": {
|
|
3112
3112
|
"@remnic/coding-graph": {
|
package/src/config.test.ts
CHANGED
|
@@ -2416,3 +2416,27 @@ test("parseConfig forwards bridgeMode as a raw passthrough (validation is in res
|
|
|
2416
2416
|
test("parseConfig leaves the OpenClaw delegate timeout to the plugin parser", () => {
|
|
2417
2417
|
assert.equal("bridgeHealthTimeoutMs" in parseConfig({ bridgeHealthTimeoutMs: 7_500 }), false);
|
|
2418
2418
|
});
|
|
2419
|
+
|
|
2420
|
+
test("parseConfig validates converge conflict policy and defaults to newest-wins", () => {
|
|
2421
|
+
assert.deepEqual(parseConfig({}).converge, { conflictPolicy: "newest-wins" });
|
|
2422
|
+
|
|
2423
|
+
for (const conflictPolicy of ["newest-wins", "manual"] as const) {
|
|
2424
|
+
assert.equal(parseConfig({ converge: { conflictPolicy } }).converge.conflictPolicy, conflictPolicy);
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
for (const conflictPolicy of ["keep-both", "", "unknown", 0, false, null]) {
|
|
2428
|
+
assert.throws(
|
|
2429
|
+
() => parseConfig({ converge: { conflictPolicy } }),
|
|
2430
|
+
/converge\.conflictPolicy.*newest-wins.*manual/,
|
|
2431
|
+
);
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
for (const converge of [0, null, [], new Date(), new Map()]) {
|
|
2435
|
+
assert.throws(() => parseConfig({ converge }), /converge must be a plain object/);
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
assert.throws(
|
|
2439
|
+
() => parseConfig({ converge: { conflictPolciy: "manual" } }),
|
|
2440
|
+
/converge contains unknown key "conflictPolciy"/,
|
|
2441
|
+
);
|
|
2442
|
+
});
|
package/src/config.ts
CHANGED
|
@@ -26,6 +26,7 @@ import type {
|
|
|
26
26
|
TriggerMode,
|
|
27
27
|
TrustWeights,
|
|
28
28
|
} from "./types.js";
|
|
29
|
+
import { parseConvergeConfig } from "./converge-config.js";
|
|
29
30
|
import { log } from "./logger.js";
|
|
30
31
|
import { cloneDefaultSessionObserverBands } from "./session-observer-bands.js";
|
|
31
32
|
import { readEnvVar, resolveHomeDir } from "./runtime/env.js";
|
|
@@ -80,6 +81,7 @@ const DEFAULT_WORKSPACE_DIR = path.join(
|
|
|
80
81
|
);
|
|
81
82
|
|
|
82
83
|
const DEFAULT_INIT_GATE_TIMEOUT_MS = 30_000;
|
|
84
|
+
|
|
83
85
|
const CLIENT_SECRET_FIELD = ["client", "Secret"].join("") as "clientSecret";
|
|
84
86
|
const REFRESH_TOKEN_FIELD = ["refresh", "Token"].join("") as "refreshToken";
|
|
85
87
|
const LEGACY_ACTIVE_RECALL_CUSTOM_FIELD = [
|
|
@@ -2332,6 +2334,7 @@ export function parseConfig(
|
|
|
2332
2334
|
procedural,
|
|
2333
2335
|
extractionLiveness: parseExtractionLivenessConfig(cfg),
|
|
2334
2336
|
replicaPeers: parseReplicaPeersConfig(cfg),
|
|
2337
|
+
converge: parseConvergeConfig(cfg.converge),
|
|
2335
2338
|
wearables,
|
|
2336
2339
|
meetings,
|
|
2337
2340
|
activity,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ConvergeConfig, ConvergeConflictPolicy } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const CONVERGE_CONFLICT_POLICIES = [
|
|
4
|
+
"newest-wins",
|
|
5
|
+
"manual",
|
|
6
|
+
] as const satisfies readonly ConvergeConflictPolicy[];
|
|
7
|
+
|
|
8
|
+
export const DEFAULT_CONVERGE_CONFLICT_POLICY: ConvergeConflictPolicy = "newest-wins";
|
|
9
|
+
|
|
10
|
+
export function parseConvergeConfig(block: unknown): ConvergeConfig {
|
|
11
|
+
if (block === undefined) {
|
|
12
|
+
return { conflictPolicy: DEFAULT_CONVERGE_CONFLICT_POLICY };
|
|
13
|
+
}
|
|
14
|
+
if (block === null || typeof block !== "object" || Array.isArray(block)) {
|
|
15
|
+
throw new Error("converge must be a plain object");
|
|
16
|
+
}
|
|
17
|
+
const prototype = Object.getPrototypeOf(block);
|
|
18
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
19
|
+
throw new Error("converge must be a plain object");
|
|
20
|
+
}
|
|
21
|
+
const { conflictPolicy, ...unknown } = block as Record<string, unknown>;
|
|
22
|
+
const unknownKey = Object.keys(unknown)[0];
|
|
23
|
+
if (unknownKey !== undefined) {
|
|
24
|
+
throw new Error(`converge contains unknown key ${JSON.stringify(unknownKey)}`);
|
|
25
|
+
}
|
|
26
|
+
if (conflictPolicy === undefined) {
|
|
27
|
+
return { conflictPolicy: DEFAULT_CONVERGE_CONFLICT_POLICY };
|
|
28
|
+
}
|
|
29
|
+
if (
|
|
30
|
+
typeof conflictPolicy === "string" &&
|
|
31
|
+
CONVERGE_CONFLICT_POLICIES.includes(conflictPolicy as ConvergeConflictPolicy)
|
|
32
|
+
) {
|
|
33
|
+
return { conflictPolicy: conflictPolicy as ConvergeConflictPolicy };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
throw new Error(
|
|
37
|
+
`converge.conflictPolicy must be one of ${CONVERGE_CONFLICT_POLICIES.join(", ")}; got ${JSON.stringify(conflictPolicy)}`
|
|
38
|
+
);
|
|
39
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1394,8 +1394,7 @@ export type {
|
|
|
1394
1394
|
CalendarSource,
|
|
1395
1395
|
RecallDisclosure,
|
|
1396
1396
|
} from "./types.js";
|
|
1397
|
-
|
|
1398
|
-
// Recall disclosure depth (issue #677).
|
|
1397
|
+
export { CONVERGE_CONFLICT_POLICIES, DEFAULT_CONVERGE_CONFLICT_POLICY } from "./converge-config.js";
|
|
1399
1398
|
export {
|
|
1400
1399
|
DEFAULT_RECALL_DISCLOSURE,
|
|
1401
1400
|
RECALL_DISCLOSURE_LEVELS,
|
|
@@ -5,6 +5,7 @@ import * as path from "node:path";
|
|
|
5
5
|
import { test } from "node:test";
|
|
6
6
|
import {
|
|
7
7
|
defaultConvergeCursorPath,
|
|
8
|
+
deriveConvergeCursorBase,
|
|
8
9
|
hashPeerNamespace,
|
|
9
10
|
normalizeConvergeCursor,
|
|
10
11
|
readConvergeCursor,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
} from "./cursor.js";
|
|
14
15
|
|
|
15
16
|
const shaA = "a".repeat(64);
|
|
17
|
+
const shaB = "b".repeat(64);
|
|
16
18
|
|
|
17
19
|
test("hashPeerNamespace: deterministic key normalization", () => {
|
|
18
20
|
const k1 = hashPeerNamespace("http://peer.example.com/", "default");
|
|
@@ -46,6 +48,18 @@ test("defaultConvergeCursorPath: constructs path under memoryDir state", () => {
|
|
|
46
48
|
assert.ok(p.endsWith(".json"));
|
|
47
49
|
});
|
|
48
50
|
|
|
51
|
+
test("deriveConvergeCursorBase retains a deferred semantic agreement", () => {
|
|
52
|
+
const semanticAgreement = {
|
|
53
|
+
local: { path: "facts/local.md", sha256: shaA },
|
|
54
|
+
peer: { path: "facts/peer.md", sha256: shaB },
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
assert.deepEqual(
|
|
58
|
+
deriveConvergeCursorBase([], "default", [semanticAgreement]).semanticAgreements,
|
|
59
|
+
[semanticAgreement]
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
49
63
|
test("normalizeConvergeCursor: validates envelope shape", () => {
|
|
50
64
|
assert.throws(() => normalizeConvergeCursor(null), /must be an object/);
|
|
51
65
|
assert.throws(() => normalizeConvergeCursor({ version: 2 }), /version must be 1/);
|
|
@@ -63,11 +77,19 @@ test("normalizeConvergeCursor: validates envelope shape", () => {
|
|
|
63
77
|
peerUrl: "http://peer",
|
|
64
78
|
namespace: "default",
|
|
65
79
|
baseFiles: [{ path: "a.md", sha256: shaA }],
|
|
80
|
+
semanticAgreements: [{
|
|
81
|
+
local: { path: "facts/local.md", sha256: shaA },
|
|
82
|
+
peer: { path: "facts/peer.md", sha256: shaB },
|
|
83
|
+
}],
|
|
66
84
|
});
|
|
67
85
|
assert.equal(valid.peerUrl, "http://peer");
|
|
68
86
|
assert.equal(valid.namespace, "default");
|
|
69
87
|
assert.equal(valid.baseFiles.length, 1);
|
|
70
88
|
assert.equal(valid.baseFiles[0]?.path, "a.md");
|
|
89
|
+
assert.deepEqual(valid.semanticAgreements, [{
|
|
90
|
+
local: { path: "facts/local.md", sha256: shaA },
|
|
91
|
+
peer: { path: "facts/peer.md", sha256: shaB },
|
|
92
|
+
}]);
|
|
71
93
|
});
|
|
72
94
|
|
|
73
95
|
test("readConvergeCursor: returns null when file is missing or invalid", async () => {
|
|
@@ -96,6 +118,10 @@ test("writeConvergeCursor & readConvergeCursor: atomic write roundtrip", async (
|
|
|
96
118
|
lastConvergedAt: new Date().toISOString(),
|
|
97
119
|
baseFiles: [{ path: "facts/a.md", sha256: shaA, bytes: 120, mtimeMs: 1000 }],
|
|
98
120
|
completedPaths: ["facts/a.md"],
|
|
121
|
+
semanticAgreements: [{
|
|
122
|
+
local: { path: "facts/local.md", sha256: shaA },
|
|
123
|
+
peer: { path: "facts/peer.md", sha256: shaB },
|
|
124
|
+
}],
|
|
99
125
|
};
|
|
100
126
|
|
|
101
127
|
await writeConvergeCursor(cursorPath, cursor);
|
|
@@ -106,6 +132,10 @@ test("writeConvergeCursor & readConvergeCursor: atomic write roundtrip", async (
|
|
|
106
132
|
assert.equal(read.baseFiles.length, 1);
|
|
107
133
|
assert.equal(read.baseFiles[0]?.sha256, shaA);
|
|
108
134
|
assert.deepEqual(read.completedPaths, ["facts/a.md"]);
|
|
135
|
+
assert.deepEqual(read.semanticAgreements, [{
|
|
136
|
+
local: { path: "facts/local.md", sha256: shaA },
|
|
137
|
+
peer: { path: "facts/peer.md", sha256: shaB },
|
|
138
|
+
}]);
|
|
109
139
|
|
|
110
140
|
// Update existing cursor atomically
|
|
111
141
|
const updated: ConvergeCursorState = {
|
package/src/reconcile/cursor.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import type { ReconcilePlanEntry, ReconcileSemanticAgreement } from "./plan.js";
|
|
4
5
|
|
|
5
6
|
export interface ConvergeCursorFileState {
|
|
6
7
|
path: string;
|
|
@@ -15,6 +16,7 @@ export interface ConvergeCursorState {
|
|
|
15
16
|
namespace: string;
|
|
16
17
|
lastConvergedAt?: string;
|
|
17
18
|
baseFiles: ConvergeCursorFileState[];
|
|
19
|
+
semanticAgreements?: ReconcileSemanticAgreement[];
|
|
18
20
|
completedPaths?: string[];
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -48,6 +50,56 @@ export function defaultConvergeCursorPath(
|
|
|
48
50
|
return path.join(path.resolve(memoryDir), ".remnic", "state", "converge-cursors", `${key}.json`);
|
|
49
51
|
}
|
|
50
52
|
|
|
53
|
+
function normalizeSemanticFileState(input: unknown): { path: string; sha256: string } | undefined {
|
|
54
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return undefined;
|
|
55
|
+
const file = input as Record<string, unknown>;
|
|
56
|
+
if (typeof file.path !== "string" || typeof file.sha256 !== "string") return undefined;
|
|
57
|
+
return { path: file.path, sha256: file.sha256 };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function digestAfterReconcile(entry: ReconcilePlanEntry): string | undefined {
|
|
61
|
+
if (entry.action === "push") return entry.localSha256;
|
|
62
|
+
if (entry.action === "pull") return entry.peerSha256;
|
|
63
|
+
if (entry.action === "conflict") {
|
|
64
|
+
if (entry.resolution === "local-wins") return entry.localSha256;
|
|
65
|
+
if (entry.resolution === "peer-wins") return entry.peerSha256;
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
if (entry.action !== "identical") return undefined;
|
|
69
|
+
if (entry.localSha256 && entry.peerSha256 && entry.localSha256 !== entry.peerSha256) return undefined;
|
|
70
|
+
return entry.localSha256 ?? entry.peerSha256;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function semanticAgreementKey(agreement: ReconcileSemanticAgreement): string {
|
|
74
|
+
return `${agreement.local.path}\0${agreement.peer.path}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function deriveConvergeCursorBase(
|
|
78
|
+
entries: readonly ReconcilePlanEntry[],
|
|
79
|
+
namespace: string,
|
|
80
|
+
priorSemanticAgreements: readonly ReconcileSemanticAgreement[] = [],
|
|
81
|
+
): Pick<ConvergeCursorState, "baseFiles" | "semanticAgreements"> {
|
|
82
|
+
const baseFiles: ConvergeCursorFileState[] = [];
|
|
83
|
+
const semanticAgreementsByPathPair = new Map(
|
|
84
|
+
priorSemanticAgreements.map((agreement) => [semanticAgreementKey(agreement), agreement])
|
|
85
|
+
);
|
|
86
|
+
for (const entry of entries) {
|
|
87
|
+
if (entry.namespace !== namespace) continue;
|
|
88
|
+
if (entry.semanticAgreement) {
|
|
89
|
+
semanticAgreementsByPathPair.set(semanticAgreementKey(entry.semanticAgreement), entry.semanticAgreement);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const sha256 = digestAfterReconcile(entry);
|
|
93
|
+
if (sha256) baseFiles.push({ path: entry.path, sha256 });
|
|
94
|
+
}
|
|
95
|
+
baseFiles.sort((left, right) => left.path.localeCompare(right.path));
|
|
96
|
+
const semanticAgreements = [...semanticAgreementsByPathPair.values()];
|
|
97
|
+
semanticAgreements.sort((left, right) =>
|
|
98
|
+
left.local.path.localeCompare(right.local.path) || left.peer.path.localeCompare(right.peer.path)
|
|
99
|
+
);
|
|
100
|
+
return { baseFiles, semanticAgreements };
|
|
101
|
+
}
|
|
102
|
+
|
|
51
103
|
export function normalizeConvergeCursor(input: unknown): ConvergeCursorState {
|
|
52
104
|
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
53
105
|
throw new Error("converge cursor must be an object");
|
|
@@ -78,6 +130,16 @@ export function normalizeConvergeCursor(input: unknown): ConvergeCursorState {
|
|
|
78
130
|
}
|
|
79
131
|
}
|
|
80
132
|
}
|
|
133
|
+
const semanticAgreements: ReconcileSemanticAgreement[] = [];
|
|
134
|
+
if (Array.isArray(obj.semanticAgreements)) {
|
|
135
|
+
for (const item of obj.semanticAgreements) {
|
|
136
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
137
|
+
const agreement = item as Record<string, unknown>;
|
|
138
|
+
const local = normalizeSemanticFileState(agreement.local);
|
|
139
|
+
const peer = normalizeSemanticFileState(agreement.peer);
|
|
140
|
+
if (local && peer) semanticAgreements.push({ local, peer });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
81
143
|
const completedPaths: string[] = [];
|
|
82
144
|
if (Array.isArray(obj.completedPaths)) {
|
|
83
145
|
for (const item of obj.completedPaths) {
|
|
@@ -92,6 +154,7 @@ export function normalizeConvergeCursor(input: unknown): ConvergeCursorState {
|
|
|
92
154
|
namespace: obj.namespace.trim(),
|
|
93
155
|
lastConvergedAt: typeof obj.lastConvergedAt === "string" ? obj.lastConvergedAt : undefined,
|
|
94
156
|
baseFiles,
|
|
157
|
+
semanticAgreements,
|
|
95
158
|
completedPaths,
|
|
96
159
|
};
|
|
97
160
|
}
|
|
@@ -132,8 +132,11 @@ test("semantic collapse prevents different active fact paths from transferring b
|
|
|
132
132
|
namespace: "default",
|
|
133
133
|
action: "identical",
|
|
134
134
|
reason: "semantic_duplicate",
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
semanticAgreement: {
|
|
136
|
+
local: localFile,
|
|
137
|
+
peer: peerFile,
|
|
138
|
+
},
|
|
139
|
+
semanticChange: "unchanged",
|
|
137
140
|
},
|
|
138
141
|
]);
|
|
139
142
|
assert.equal(collapsed.byNamespace[0]?.identical, 1);
|
|
@@ -141,6 +144,51 @@ test("semantic collapse prevents different active fact paths from transferring b
|
|
|
141
144
|
assert.equal(collapsed.byNamespace[0]?.push, 0);
|
|
142
145
|
});
|
|
143
146
|
|
|
147
|
+
test("semantic collapse classifies a later one-sided metadata edit from its per-side base", () => {
|
|
148
|
+
const semanticHash = ContentHashIndex.computeHash("same active fact");
|
|
149
|
+
const priorLocal = { path: "facts/local-id.md", sha256: "a".repeat(64) };
|
|
150
|
+
const currentLocal = { ...priorLocal, sha256: "c".repeat(64) };
|
|
151
|
+
const peerFile = { path: "facts/peer-id.md", sha256: "b".repeat(64) };
|
|
152
|
+
const manifest = (file: typeof currentLocal): ReconcileManifest => ({
|
|
153
|
+
format: "remnic-reconcile-manifest",
|
|
154
|
+
schemaVersion: 1,
|
|
155
|
+
files: [{
|
|
156
|
+
...file,
|
|
157
|
+
memory: {
|
|
158
|
+
id: file.path,
|
|
159
|
+
category: "fact",
|
|
160
|
+
contentHash: semanticHash,
|
|
161
|
+
status: "active",
|
|
162
|
+
},
|
|
163
|
+
}],
|
|
164
|
+
});
|
|
165
|
+
const plan = planReconciliation([{
|
|
166
|
+
namespace: "default",
|
|
167
|
+
local: [currentLocal],
|
|
168
|
+
peer: [peerFile],
|
|
169
|
+
}]);
|
|
170
|
+
|
|
171
|
+
const collapsed = collapseActiveFactDuplicates(
|
|
172
|
+
plan,
|
|
173
|
+
new Map([["default", manifest(currentLocal)]]),
|
|
174
|
+
new Map([["default", manifest(peerFile)]]),
|
|
175
|
+
new Map([["default", [{ local: priorLocal, peer: peerFile }]]])
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
assert.deepEqual(collapsed.entries, [{
|
|
179
|
+
path: currentLocal.path,
|
|
180
|
+
namespace: "default",
|
|
181
|
+
action: "identical",
|
|
182
|
+
reason: "semantic_duplicate",
|
|
183
|
+
semanticAgreement: {
|
|
184
|
+
local: currentLocal,
|
|
185
|
+
peer: peerFile,
|
|
186
|
+
},
|
|
187
|
+
semanticChange: "local_changed",
|
|
188
|
+
}]);
|
|
189
|
+
assert.equal(collapsed.converged, true);
|
|
190
|
+
});
|
|
191
|
+
|
|
144
192
|
test("semantic collapse does not fold non-active facts or unrelated path conflicts", () => {
|
|
145
193
|
const semanticHash = ContentHashIndex.computeHash("same inactive fact");
|
|
146
194
|
const localFile = { path: "facts/local.md", sha256: "a".repeat(64) };
|
|
@@ -215,6 +263,49 @@ test("semantic collapse preserves same-path metadata updates", () => {
|
|
|
215
263
|
assert.equal(collapsed.entries[0]?.action, "push");
|
|
216
264
|
});
|
|
217
265
|
|
|
266
|
+
test("semantic collapse preserves a shared-path metadata update when peer canonical path differs", () => {
|
|
267
|
+
const semanticHash = ContentHashIndex.computeHash("same raw fact");
|
|
268
|
+
const sharedLocal = { path: "facts/b.md", sha256: "a".repeat(64) };
|
|
269
|
+
const sharedPeer = { path: "facts/b.md", sha256: "b".repeat(64) };
|
|
270
|
+
const peerDuplicate = { path: "facts/a.md", sha256: "c".repeat(64) };
|
|
271
|
+
const plan = planReconciliation([{
|
|
272
|
+
namespace: "default",
|
|
273
|
+
local: [sharedLocal],
|
|
274
|
+
peer: [peerDuplicate, sharedPeer],
|
|
275
|
+
base: [{ path: sharedPeer.path, sha256: sharedPeer.sha256 }],
|
|
276
|
+
}]);
|
|
277
|
+
const manifest = (files: Array<{ path: string; sha256: string }>): ReconcileManifest => ({
|
|
278
|
+
format: "remnic-reconcile-manifest",
|
|
279
|
+
schemaVersion: 1,
|
|
280
|
+
files: files.map((file) => ({
|
|
281
|
+
...file,
|
|
282
|
+
memory: {
|
|
283
|
+
id: file.path,
|
|
284
|
+
category: "fact",
|
|
285
|
+
contentHash: semanticHash,
|
|
286
|
+
status: "active",
|
|
287
|
+
},
|
|
288
|
+
})),
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
const collapsed = collapseActiveFactDuplicates(
|
|
292
|
+
plan,
|
|
293
|
+
new Map([["default", manifest([sharedLocal])]]),
|
|
294
|
+
new Map([["default", manifest([peerDuplicate, sharedPeer])]])
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
assert.deepEqual(collapsed.entries, [{
|
|
298
|
+
path: sharedLocal.path,
|
|
299
|
+
namespace: "default",
|
|
300
|
+
action: "push",
|
|
301
|
+
reason: "local_changed",
|
|
302
|
+
localSha256: sharedLocal.sha256,
|
|
303
|
+
peerSha256: sharedPeer.sha256,
|
|
304
|
+
baseSha256: sharedPeer.sha256,
|
|
305
|
+
}]);
|
|
306
|
+
assert.equal(collapsed.converged, false);
|
|
307
|
+
});
|
|
308
|
+
|
|
218
309
|
test("semantic collapse remains converged after transferring the canonical one-sided duplicate", () => {
|
|
219
310
|
const semanticHash = ContentHashIndex.computeHash("same one-sided fact");
|
|
220
311
|
const canonical = { path: "facts/a.md", sha256: "a".repeat(64) };
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
type ReconcileFileState,
|
|
8
8
|
type ReconcilePlan,
|
|
9
9
|
type ReconcilePlanEntry,
|
|
10
|
+
type ReconcileSemanticAgreement,
|
|
11
|
+
type ReconcileSemanticChange,
|
|
10
12
|
summarizeReconcilePlan,
|
|
11
13
|
} from "./plan.js";
|
|
12
14
|
|
|
@@ -153,10 +155,28 @@ function comparePlanEntries(left: ReconcilePlanEntry, right: ReconcilePlanEntry)
|
|
|
153
155
|
return left.path < right.path ? -1 : left.path > right.path ? 1 : 0;
|
|
154
156
|
}
|
|
155
157
|
|
|
158
|
+
function semanticAgreementKey(agreement: ReconcileSemanticAgreement): string {
|
|
159
|
+
return `${agreement.local.path}\0${agreement.peer.path}`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function classifySemanticChange(
|
|
163
|
+
current: ReconcileSemanticAgreement,
|
|
164
|
+
prior: ReconcileSemanticAgreement | undefined
|
|
165
|
+
): ReconcileSemanticChange {
|
|
166
|
+
if (!prior) return "unchanged";
|
|
167
|
+
const localChanged = current.local.sha256 !== prior.local.sha256;
|
|
168
|
+
const peerChanged = current.peer.sha256 !== prior.peer.sha256;
|
|
169
|
+
if (localChanged && peerChanged) return "both_modified";
|
|
170
|
+
if (localChanged) return "local_changed";
|
|
171
|
+
if (peerChanged) return "peer_changed";
|
|
172
|
+
return "unchanged";
|
|
173
|
+
}
|
|
174
|
+
|
|
156
175
|
export function collapseActiveFactDuplicates(
|
|
157
176
|
plan: ReconcilePlan,
|
|
158
177
|
localManifests: ReadonlyMap<string, ReconcileManifest>,
|
|
159
|
-
peerManifests: ReadonlyMap<string, ReconcileManifest
|
|
178
|
+
peerManifests: ReadonlyMap<string, ReconcileManifest>,
|
|
179
|
+
priorSemanticAgreements?: ReadonlyMap<string, readonly ReconcileSemanticAgreement[]>,
|
|
160
180
|
): ReconcilePlan {
|
|
161
181
|
const entriesByNamespace = new Map<string, ReconcilePlanEntry[]>();
|
|
162
182
|
for (const entry of plan.entries) {
|
|
@@ -174,6 +194,12 @@ export function collapseActiveFactDuplicates(
|
|
|
174
194
|
const peerByPath = activeFactByPath(peerManifest);
|
|
175
195
|
const localFilesByPath = new Map((localManifest?.files ?? []).map((file) => [file.path, file]));
|
|
176
196
|
const peerFilesByPath = new Map((peerManifest?.files ?? []).map((file) => [file.path, file]));
|
|
197
|
+
const priorSemanticByPathPair = new Map(
|
|
198
|
+
(priorSemanticAgreements?.get(namespace) ?? []).map((agreement) => [
|
|
199
|
+
semanticAgreementKey(agreement),
|
|
200
|
+
agreement,
|
|
201
|
+
])
|
|
202
|
+
);
|
|
177
203
|
const localByHash = new Map<string, ActiveFactManifestFile[]>();
|
|
178
204
|
const peerByHash = new Map<string, ActiveFactManifestFile[]>();
|
|
179
205
|
|
|
@@ -214,6 +240,26 @@ export function collapseActiveFactDuplicates(
|
|
|
214
240
|
...localCandidates.map((file) => file.path),
|
|
215
241
|
...peerCandidates.map((file) => file.path),
|
|
216
242
|
]);
|
|
243
|
+
const authoritativeSamePathEntries = new Set(entries.filter(
|
|
244
|
+
(entry) =>
|
|
245
|
+
duplicatePaths.has(entry.path)
|
|
246
|
+
&& localFilesByPath.has(entry.path)
|
|
247
|
+
&& peerFilesByPath.has(entry.path)
|
|
248
|
+
&& entry.action !== "identical"
|
|
249
|
+
));
|
|
250
|
+
if (authoritativeSamePathEntries.size > 0) {
|
|
251
|
+
for (const entry of entries) {
|
|
252
|
+
if (
|
|
253
|
+
duplicatePaths.has(entry.path)
|
|
254
|
+
&& !authoritativeSamePathEntries.has(entry)
|
|
255
|
+
&& (entry.action === "pull" || entry.action === "push" || entry.action === "identical")
|
|
256
|
+
) {
|
|
257
|
+
removed.add(entry);
|
|
258
|
+
changed = true;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
217
263
|
const unsafeEntry = entries.some(
|
|
218
264
|
(entry) => duplicatePaths.has(entry.path) && (entry.action === "suppress" || entry.action === "conflict")
|
|
219
265
|
);
|
|
@@ -226,13 +272,20 @@ export function collapseActiveFactDuplicates(
|
|
|
226
272
|
removed.add(entry);
|
|
227
273
|
}
|
|
228
274
|
}
|
|
275
|
+
const semanticAgreement: ReconcileSemanticAgreement = {
|
|
276
|
+
local: { path: localPath, sha256: localFile.sha256 },
|
|
277
|
+
peer: { path: peerPath, sha256: peerFile.sha256 },
|
|
278
|
+
};
|
|
229
279
|
replacements.push({
|
|
230
280
|
path: localPath < peerPath ? localPath : peerPath,
|
|
231
281
|
namespace,
|
|
232
282
|
action: "identical",
|
|
233
283
|
reason: "semantic_duplicate",
|
|
234
|
-
|
|
235
|
-
|
|
284
|
+
semanticAgreement,
|
|
285
|
+
semanticChange: classifySemanticChange(
|
|
286
|
+
semanticAgreement,
|
|
287
|
+
priorSemanticByPathPair.get(semanticAgreementKey(semanticAgreement))
|
|
288
|
+
),
|
|
236
289
|
});
|
|
237
290
|
changed = true;
|
|
238
291
|
continue;
|