@remnic/core 9.69.17 → 9.69.18
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 +18 -18
- package/dist/access-authorization-probe.d.ts +11 -11
- package/dist/access-authorization-probe.js +19 -19
- package/dist/access-boundary.d.ts +11 -11
- package/dist/access-boundary.js +18 -18
- package/dist/access-cli.js +55 -55
- 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 +18 -18
- 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 +20 -20
- package/dist/access-http.d.ts +12 -12
- package/dist/access-http.js +31 -31
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +18 -18
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +18 -18
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +25 -25
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-Rzuo1nGR.d.ts → access-namespace-preflight-BMHhxoL9.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +18 -18
- package/dist/access-observe-transcript.d.ts +9 -9
- package/dist/access-observe-write-surface.d.ts +11 -11
- package/dist/access-observe-write-surface.js +18 -18
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-offline-manifest.js +4 -4
- package/dist/access-operations-batch.js +19 -19
- package/dist/access-operations.d.ts +12 -12
- package/dist/access-operations.js +24 -24
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +18 -18
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +18 -18
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +18 -18
- package/dist/{access-service-DmDS8Y5P.d.ts → access-service-CYdqPfpS.d.ts} +13 -13
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +18 -18
- package/dist/access-surface-catalog.d.ts +11 -11
- package/dist/access-surface-catalog.js +20 -20
- 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 +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 +3 -3
- 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-DjTLVOYp.d.ts → catalog-C1qHsGew.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +4 -4
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-X66BHMAU.js → chunk-2J4TIFBK.js} +2 -2
- package/dist/{chunk-I672YBXY.js → chunk-3LADWWMA.js} +3 -3
- package/dist/{chunk-DBLVQROL.js → chunk-3LJPSRAN.js} +2 -2
- package/dist/{chunk-S6ZZOFVJ.js → chunk-43HMVVOL.js} +2 -2
- package/dist/{chunk-IDZU6I4H.js → chunk-4HYNMLT6.js} +2 -2
- package/dist/{chunk-HTOWFFAI.js → chunk-5CF2R4NS.js} +2 -2
- package/dist/{chunk-XR6LLNLU.js → chunk-5MF4EGL5.js} +21 -21
- package/dist/{chunk-SJ5JGIBT.js → chunk-5SGOARQJ.js} +2 -2
- package/dist/chunk-6MINUTGJ.js +64 -0
- package/dist/chunk-6MINUTGJ.js.map +1 -0
- package/dist/{chunk-5J36BYRI.js → chunk-7TUB6JWA.js} +3 -3
- package/dist/{chunk-GI726D4G.js → chunk-AWF4CNYJ.js} +2 -2
- package/dist/{chunk-J6HRJ37H.js → chunk-B2AGUKSS.js} +2 -2
- package/dist/{chunk-WMZ6F7GY.js → chunk-BR3OOQZQ.js} +2 -2
- package/dist/{chunk-YYP5GM6J.js → chunk-BZTJEILZ.js} +2 -2
- package/dist/{chunk-NYFWBYY4.js → chunk-CASWJ2HM.js} +2 -2
- package/dist/{chunk-B67W7CBL.js → chunk-CFKCFY4B.js} +2 -2
- package/dist/{chunk-5Z6JYMK4.js → chunk-CVJMGVEW.js} +22 -22
- package/dist/{chunk-DA4ZMCBU.js → chunk-D5ZNOKR7.js} +3 -3
- package/dist/{chunk-LE7B5ETE.js → chunk-DK6GMO6D.js} +3 -3
- package/dist/{chunk-EYKDBZB3.js → chunk-DP4EBV7C.js} +2 -2
- package/dist/{chunk-WOEKJPJG.js → chunk-EFCBJDYE.js} +3 -3
- package/dist/{chunk-3ZAZ77WB.js → chunk-EJ5RKUXW.js} +2 -2
- package/dist/{chunk-5CX3NSR7.js → chunk-F5UWQ4LX.js} +2 -2
- package/dist/{chunk-CM3JBYD4.js → chunk-FB7LAJQM.js} +2 -2
- package/dist/{chunk-IO4OJ73B.js → chunk-G6N654ND.js} +8 -8
- package/dist/{chunk-W7M7NKR7.js → chunk-GGYDJJBO.js} +2 -2
- package/dist/{chunk-MAIBNEB6.js → chunk-HOUST5UX.js} +2 -2
- package/dist/{chunk-X73YCO3E.js → chunk-I7FY43VC.js} +2 -2
- package/dist/{chunk-376CEAYL.js → chunk-IZZ7Q2RJ.js} +12 -12
- package/dist/{chunk-ZRUEP4IK.js → chunk-JIM4BIOC.js} +30 -49
- package/dist/chunk-JIM4BIOC.js.map +1 -0
- package/dist/{chunk-NF3NMAG7.js → chunk-JOYC4RYC.js} +2 -2
- package/dist/{chunk-ROHBPMWD.js → chunk-JZ6EYAVP.js} +2 -2
- package/dist/{chunk-5DRBG5U6.js → chunk-KA2HZCMG.js} +2 -2
- package/dist/{chunk-ETZ7KKOS.js → chunk-KTVSPFCQ.js} +2 -2
- package/dist/{chunk-XAJWPB2V.js → chunk-L74A6NTI.js} +5 -5
- package/dist/{chunk-V5RWV5DK.js → chunk-LFK623SF.js} +2 -2
- package/dist/{chunk-AYHPGLG6.js → chunk-N7JK2RKG.js} +2 -2
- package/dist/{chunk-QFMFZILG.js → chunk-NYRB7BKY.js} +2 -2
- package/dist/{chunk-YCJASQMN.js → chunk-NZGO2GKL.js} +2 -2
- package/dist/{chunk-N3DSSCOR.js → chunk-OGTKQ5MJ.js} +2 -2
- package/dist/{chunk-CWPVXVIT.js → chunk-PC7WNIRL.js} +10 -10
- package/dist/{chunk-NCUODVUI.js → chunk-PPOT6SPR.js} +5 -5
- package/dist/{chunk-FCL6ENLF.js → chunk-R7LY4YKF.js} +2 -2
- package/dist/{chunk-FK2SJX27.js → chunk-RO2X2EYM.js} +2 -2
- package/dist/{chunk-WP37SBRE.js → chunk-S37NN23M.js} +2 -2
- package/dist/{chunk-DDX6KIXF.js → chunk-SB4OBB7P.js} +2 -2
- package/dist/{chunk-WHO6ITU7.js → chunk-UMEOXLIZ.js} +2 -2
- package/dist/{chunk-NISCAOSR.js → chunk-WL5PR5YC.js} +2 -2
- package/dist/{chunk-YYE5MKRX.js → chunk-X33MJFD2.js} +2 -2
- package/dist/{chunk-NAOAZASM.js → chunk-XJJLWTLW.js} +3 -3
- package/dist/{chunk-OYV6RKPM.js → chunk-XOQGUGJL.js} +2 -6
- package/dist/chunk-XOQGUGJL.js.map +1 -0
- package/dist/{chunk-Y7E5SUZ6.js → chunk-YVLENSNS.js} +2 -2
- package/dist/{chunk-DGKQVGLC.js → chunk-ZJWDWPX6.js} +3 -3
- package/dist/{chunk-EQEP23JK.js → chunk-ZL3XX5LW.js} +2 -2
- package/dist/{chunk-GF7QLY6E.js → chunk-ZZM476NV.js} +1 -1
- package/dist/{cli-CYQIKncA.d.ts → cli-DN9LpWf0.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +45 -45
- package/dist/coding/export-okf-codegraph.d.ts +1 -1
- package/dist/coding/export-okf-codegraph.js +3 -3
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +3 -3
- 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 +2 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +3 -3
- 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 +16 -2
- package/dist/converge-config.js +9 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +5 -5
- 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 +5 -5
- package/dist/cross-lingual-recall.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/deep-recall-http-glue.d.ts +11 -11
- package/dist/deep-recall-mcp-tools.d.ts +11 -11
- package/dist/deep-recall-policy-llm.d.ts +1 -1
- package/dist/deep-recall-seeds.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-37JdQv_3.d.ts → dependency-propagation-delivery-DjpUlhLi.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 +3 -3
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/eval-trajectory-contracts.d.ts +1 -1
- package/dist/eval-trajectory-store.d.ts +1 -1
- package/dist/eval-trajectory.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/external-wiki-access.d.ts +11 -11
- package/dist/external-wiki-access.js +19 -19
- 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 +3 -3
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/{index-DquhYqsc.d.ts → index-CsUrdMyL.d.ts} +2 -2
- package/dist/index.d.ts +26 -26
- package/dist/index.js +66 -56
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/location/index.d.ts +3 -3
- package/dist/location/index.js +5 -5
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/{maintenance-CizZOycr.d.ts → maintenance-D1GRGLTE.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -11
- 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 +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +4 -4
- 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 +3 -3
- 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 +6 -6
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +13 -13
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +11 -11
- package/dist/{orchestrator-DqLcuNMP.d.ts → orchestrator-DeqaPGT5.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +55 -55
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-DbJpmcRu.d.ts → pipeline-umUzU0D1.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-C_hWt6I8.d.ts → public-http-C1ht4oDJ.d.ts} +1 -1
- package/dist/{qmd-DA_7fbSz.d.ts → qmd-BasT78PP.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-navigate-access.d.ts +1 -1
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.d.ts +1 -1
- package/dist/recall-navigate-disclosure.js +1 -1
- package/dist/recall-navigate.d.ts +1 -1
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/cursor.js +2 -2
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/manifest.js +3 -3
- package/dist/reconcile/plan.d.ts +16 -1
- package/dist/reconcile/plan.js +2 -2
- 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 +3 -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/schemas.d.ts +42 -42
- package/dist/{scope-profiles-BpiWKZzx.d.ts → scope-profiles-DXYzyOXW.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-NJpaZpkY.d.ts → semantic-consolidation-CqDeaY0U.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/{service-DdlZjX1D.d.ts → service-BKD-DVYZ.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 +3 -3
- package/dist/standup/build.js +3 -3
- package/dist/{storage-C7BWrpU9.d.ts → storage-BcFd1lN_.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +2 -2
- 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 +21 -21
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/export-okf.d.ts +1 -1
- package/dist/transfer/export-okf.js +4 -4
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-Cy1l6fzp.d.ts → types-BRg3tMyp.d.ts} +2 -0
- 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 +3 -3
- package/dist/who-knows-cli.d.ts +11 -11
- package/dist/who-knows-cli.js +4 -4
- package/dist/who-knows.d.ts +11 -11
- package/dist/who-knows.js +3 -3
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/converge-config.ts +40 -3
- package/src/index.ts +1 -1
- package/src/reconcile/plan.test.ts +118 -88
- package/src/reconcile/plan.ts +98 -84
- package/src/types.ts +47 -44
- package/dist/chunk-HBVPYRDW.js +0 -39
- package/dist/chunk-HBVPYRDW.js.map +0 -1
- package/dist/chunk-OYV6RKPM.js.map +0 -1
- package/dist/chunk-ZRUEP4IK.js.map +0 -1
- /package/dist/{chunk-X66BHMAU.js.map → chunk-2J4TIFBK.js.map} +0 -0
- /package/dist/{chunk-I672YBXY.js.map → chunk-3LADWWMA.js.map} +0 -0
- /package/dist/{chunk-DBLVQROL.js.map → chunk-3LJPSRAN.js.map} +0 -0
- /package/dist/{chunk-S6ZZOFVJ.js.map → chunk-43HMVVOL.js.map} +0 -0
- /package/dist/{chunk-IDZU6I4H.js.map → chunk-4HYNMLT6.js.map} +0 -0
- /package/dist/{chunk-HTOWFFAI.js.map → chunk-5CF2R4NS.js.map} +0 -0
- /package/dist/{chunk-XR6LLNLU.js.map → chunk-5MF4EGL5.js.map} +0 -0
- /package/dist/{chunk-SJ5JGIBT.js.map → chunk-5SGOARQJ.js.map} +0 -0
- /package/dist/{chunk-5J36BYRI.js.map → chunk-7TUB6JWA.js.map} +0 -0
- /package/dist/{chunk-GI726D4G.js.map → chunk-AWF4CNYJ.js.map} +0 -0
- /package/dist/{chunk-J6HRJ37H.js.map → chunk-B2AGUKSS.js.map} +0 -0
- /package/dist/{chunk-WMZ6F7GY.js.map → chunk-BR3OOQZQ.js.map} +0 -0
- /package/dist/{chunk-YYP5GM6J.js.map → chunk-BZTJEILZ.js.map} +0 -0
- /package/dist/{chunk-NYFWBYY4.js.map → chunk-CASWJ2HM.js.map} +0 -0
- /package/dist/{chunk-B67W7CBL.js.map → chunk-CFKCFY4B.js.map} +0 -0
- /package/dist/{chunk-5Z6JYMK4.js.map → chunk-CVJMGVEW.js.map} +0 -0
- /package/dist/{chunk-DA4ZMCBU.js.map → chunk-D5ZNOKR7.js.map} +0 -0
- /package/dist/{chunk-LE7B5ETE.js.map → chunk-DK6GMO6D.js.map} +0 -0
- /package/dist/{chunk-EYKDBZB3.js.map → chunk-DP4EBV7C.js.map} +0 -0
- /package/dist/{chunk-WOEKJPJG.js.map → chunk-EFCBJDYE.js.map} +0 -0
- /package/dist/{chunk-3ZAZ77WB.js.map → chunk-EJ5RKUXW.js.map} +0 -0
- /package/dist/{chunk-5CX3NSR7.js.map → chunk-F5UWQ4LX.js.map} +0 -0
- /package/dist/{chunk-CM3JBYD4.js.map → chunk-FB7LAJQM.js.map} +0 -0
- /package/dist/{chunk-IO4OJ73B.js.map → chunk-G6N654ND.js.map} +0 -0
- /package/dist/{chunk-W7M7NKR7.js.map → chunk-GGYDJJBO.js.map} +0 -0
- /package/dist/{chunk-MAIBNEB6.js.map → chunk-HOUST5UX.js.map} +0 -0
- /package/dist/{chunk-X73YCO3E.js.map → chunk-I7FY43VC.js.map} +0 -0
- /package/dist/{chunk-376CEAYL.js.map → chunk-IZZ7Q2RJ.js.map} +0 -0
- /package/dist/{chunk-NF3NMAG7.js.map → chunk-JOYC4RYC.js.map} +0 -0
- /package/dist/{chunk-ROHBPMWD.js.map → chunk-JZ6EYAVP.js.map} +0 -0
- /package/dist/{chunk-5DRBG5U6.js.map → chunk-KA2HZCMG.js.map} +0 -0
- /package/dist/{chunk-ETZ7KKOS.js.map → chunk-KTVSPFCQ.js.map} +0 -0
- /package/dist/{chunk-XAJWPB2V.js.map → chunk-L74A6NTI.js.map} +0 -0
- /package/dist/{chunk-V5RWV5DK.js.map → chunk-LFK623SF.js.map} +0 -0
- /package/dist/{chunk-AYHPGLG6.js.map → chunk-N7JK2RKG.js.map} +0 -0
- /package/dist/{chunk-QFMFZILG.js.map → chunk-NYRB7BKY.js.map} +0 -0
- /package/dist/{chunk-YCJASQMN.js.map → chunk-NZGO2GKL.js.map} +0 -0
- /package/dist/{chunk-N3DSSCOR.js.map → chunk-OGTKQ5MJ.js.map} +0 -0
- /package/dist/{chunk-CWPVXVIT.js.map → chunk-PC7WNIRL.js.map} +0 -0
- /package/dist/{chunk-NCUODVUI.js.map → chunk-PPOT6SPR.js.map} +0 -0
- /package/dist/{chunk-FCL6ENLF.js.map → chunk-R7LY4YKF.js.map} +0 -0
- /package/dist/{chunk-FK2SJX27.js.map → chunk-RO2X2EYM.js.map} +0 -0
- /package/dist/{chunk-WP37SBRE.js.map → chunk-S37NN23M.js.map} +0 -0
- /package/dist/{chunk-DDX6KIXF.js.map → chunk-SB4OBB7P.js.map} +0 -0
- /package/dist/{chunk-WHO6ITU7.js.map → chunk-UMEOXLIZ.js.map} +0 -0
- /package/dist/{chunk-NISCAOSR.js.map → chunk-WL5PR5YC.js.map} +0 -0
- /package/dist/{chunk-YYE5MKRX.js.map → chunk-X33MJFD2.js.map} +0 -0
- /package/dist/{chunk-NAOAZASM.js.map → chunk-XJJLWTLW.js.map} +0 -0
- /package/dist/{chunk-Y7E5SUZ6.js.map → chunk-YVLENSNS.js.map} +0 -0
- /package/dist/{chunk-DGKQVGLC.js.map → chunk-ZJWDWPX6.js.map} +0 -0
- /package/dist/{chunk-EQEP23JK.js.map → chunk-ZL3XX5LW.js.map} +0 -0
- /package/dist/{chunk-GF7QLY6E.js.map → chunk-ZZM476NV.js.map} +0 -0
|
@@ -33,7 +33,7 @@ test("converged corpora produce no work and report converged", () => {
|
|
|
33
33
|
assert.equal(plan.converged, true);
|
|
34
34
|
assert.deepEqual(
|
|
35
35
|
plan.entries.map((e) => e.action),
|
|
36
|
-
["identical", "identical"]
|
|
36
|
+
["identical", "identical"]
|
|
37
37
|
);
|
|
38
38
|
assert.deepEqual(plan.byNamespace, [
|
|
39
39
|
{ namespace: "default", pull: 0, push: 0, identical: 2, conflict: 0, suppress: 0, unresolved: 0 },
|
|
@@ -56,7 +56,7 @@ test("a bootstrap merge moves unique data both ways and deletes nothing", () =>
|
|
|
56
56
|
assert.equal(
|
|
57
57
|
plan.entries.filter((e) => e.action === "conflict").length,
|
|
58
58
|
0,
|
|
59
|
-
"absent on one side without a base means never seen, not deleted"
|
|
59
|
+
"absent on one side without a base means never seen, not deleted"
|
|
60
60
|
);
|
|
61
61
|
});
|
|
62
62
|
|
|
@@ -79,7 +79,7 @@ test("newest-wins picks the later side by mtime", () => {
|
|
|
79
79
|
local: [file("facts/a.md", "local", 2000), file("facts/b.md", "local", 1000)],
|
|
80
80
|
peer: [file("facts/a.md", "peer", 1000), file("facts/b.md", "peer", 2000)],
|
|
81
81
|
},
|
|
82
|
-
{ conflictPolicy: "newest-wins" }
|
|
82
|
+
{ conflictPolicy: "newest-wins" }
|
|
83
83
|
);
|
|
84
84
|
assert.equal(entryFor(entries, "facts/a.md").resolution, "local-wins");
|
|
85
85
|
assert.equal(entryFor(entries, "facts/b.md").resolution, "peer-wins");
|
|
@@ -95,13 +95,12 @@ test("newest-wins degrades to keeping both when the order is not decidable", ()
|
|
|
95
95
|
local: [file("facts/untimed.md", "local"), file("facts/tied.md", "local", 5000)],
|
|
96
96
|
peer: [file("facts/untimed.md", "peer", 1000), file("facts/tied.md", "peer", 5000)],
|
|
97
97
|
},
|
|
98
|
-
{ conflictPolicy: "newest-wins" }
|
|
98
|
+
{ conflictPolicy: "newest-wins" }
|
|
99
99
|
);
|
|
100
100
|
assert.equal(entryFor(entries, "facts/untimed.md").resolution, "supersede-link");
|
|
101
101
|
assert.equal(entryFor(entries, "facts/tied.md").resolution, "supersede-link");
|
|
102
102
|
});
|
|
103
103
|
|
|
104
|
-
|
|
105
104
|
test("a base turns a one-sided change back into an ordinary transfer", () => {
|
|
106
105
|
const base = [file("facts/a.md", "v1"), file("facts/b.md", "v1")];
|
|
107
106
|
const entries = planNamespaceReconciliation({
|
|
@@ -216,7 +215,7 @@ test("newest-wins compares delete revision times with surviving modifications",
|
|
|
216
215
|
["facts/peer-deletion-wins.md", 3000],
|
|
217
216
|
]),
|
|
218
217
|
},
|
|
219
|
-
{ conflictPolicy: "newest-wins" }
|
|
218
|
+
{ conflictPolicy: "newest-wins" }
|
|
220
219
|
);
|
|
221
220
|
assert.equal(entryFor(entries, "facts/local-modification-wins.md").resolution, "local-wins");
|
|
222
221
|
assert.equal(entryFor(entries, "facts/peer-deletion-wins.md").resolution, "peer-wins");
|
|
@@ -237,7 +236,10 @@ test("namespaces are planned independently and reported separately", () => {
|
|
|
237
236
|
assert.equal(plan.entries.length, 2);
|
|
238
237
|
assert.equal(plan.entries.filter((e) => e.namespace === "alpha")[0]?.action, "push");
|
|
239
238
|
assert.equal(plan.entries.filter((e) => e.namespace === "beta")[0]?.action, "pull");
|
|
240
|
-
assert.deepEqual(
|
|
239
|
+
assert.deepEqual(
|
|
240
|
+
plan.byNamespace.map((r) => r.namespace),
|
|
241
|
+
["alpha", "beta"]
|
|
242
|
+
);
|
|
241
243
|
});
|
|
242
244
|
|
|
243
245
|
test("the plan is byte-stable across runs regardless of input order", () => {
|
|
@@ -256,8 +258,16 @@ test("the plan is byte-stable across runs regardless of input order", () => {
|
|
|
256
258
|
assert.deepEqual(first.entries, second.entries);
|
|
257
259
|
assert.deepEqual(
|
|
258
260
|
first.entries.map((e) => `${e.namespace}:${e.path}`),
|
|
259
|
-
[
|
|
260
|
-
"
|
|
261
|
+
[
|
|
262
|
+
"alpha:facts/a.md",
|
|
263
|
+
"alpha:facts/b.md",
|
|
264
|
+
"alpha:facts/c.md",
|
|
265
|
+
"alpha:facts/z.md",
|
|
266
|
+
"beta:facts/a.md",
|
|
267
|
+
"beta:facts/b.md",
|
|
268
|
+
"beta:facts/c.md",
|
|
269
|
+
"beta:facts/z.md",
|
|
270
|
+
]
|
|
261
271
|
);
|
|
262
272
|
});
|
|
263
273
|
|
|
@@ -315,7 +325,7 @@ test("streaming the local side still reports every peer-only path exactly once",
|
|
|
315
325
|
});
|
|
316
326
|
assert.deepEqual(
|
|
317
327
|
entries.filter((e) => e.action === "pull").map((e) => e.path),
|
|
318
|
-
["facts/p1.md", "facts/p2.md"]
|
|
328
|
+
["facts/p1.md", "facts/p2.md"]
|
|
319
329
|
);
|
|
320
330
|
});
|
|
321
331
|
|
|
@@ -345,7 +355,7 @@ test("a retracted peer revision cannot win a conflict", () => {
|
|
|
345
355
|
peer: [file("facts/a.md", "retracted", 9000)],
|
|
346
356
|
tombstonedFileSha256: [digest("retracted")],
|
|
347
357
|
},
|
|
348
|
-
{ conflictPolicy: "newest-wins" }
|
|
358
|
+
{ conflictPolicy: "newest-wins" }
|
|
349
359
|
);
|
|
350
360
|
const entry = entryFor(entries, "facts/a.md");
|
|
351
361
|
assert.equal(entry.action, "suppress");
|
|
@@ -362,7 +372,7 @@ test("a malformed census record fails the plan instead of vanishing from it", ()
|
|
|
362
372
|
peer: side === "peer" ? [{ path: "", sha256: digest("x") }] : [],
|
|
363
373
|
}),
|
|
364
374
|
ReconcilePlanInputError,
|
|
365
|
-
`${side} census with an empty path must reject
|
|
375
|
+
`${side} census with an empty path must reject`
|
|
366
376
|
);
|
|
367
377
|
}
|
|
368
378
|
});
|
|
@@ -379,7 +389,7 @@ test("a path listed twice with different digests is rejected on every census", (
|
|
|
379
389
|
base: side === "base" ? dupe : undefined,
|
|
380
390
|
}),
|
|
381
391
|
/lists facts\/a\.md twice with different digests/,
|
|
382
|
-
`${side} census must not silently pick a winner by arrival order
|
|
392
|
+
`${side} census must not silently pick a winner by arrival order`
|
|
383
393
|
);
|
|
384
394
|
}
|
|
385
395
|
// An exact repeat is unambiguous and stays acceptable.
|
|
@@ -388,7 +398,7 @@ test("a path listed twice with different digests is rejected on every census", (
|
|
|
388
398
|
namespace: "default",
|
|
389
399
|
local: [file("facts/a.md", "one"), file("facts/a.md", "one")],
|
|
390
400
|
peer: [],
|
|
391
|
-
})
|
|
401
|
+
})
|
|
392
402
|
);
|
|
393
403
|
});
|
|
394
404
|
|
|
@@ -398,9 +408,9 @@ test("an unknown conflictPolicy is rejected rather than silently treated as manu
|
|
|
398
408
|
planNamespaceReconciliation(
|
|
399
409
|
{ namespace: "default", local: [file("facts/a.md", "l")], peer: [file("facts/a.md", "p")] },
|
|
400
410
|
// Deserialized config or an untyped JS caller can produce this.
|
|
401
|
-
{ conflictPolicy: "newest_wins" as unknown as "newest-wins" }
|
|
411
|
+
{ conflictPolicy: "newest_wins" as unknown as "newest-wins" }
|
|
402
412
|
),
|
|
403
|
-
ReconcilePlanInputError
|
|
413
|
+
ReconcilePlanInputError
|
|
404
414
|
);
|
|
405
415
|
});
|
|
406
416
|
|
|
@@ -426,7 +436,7 @@ test("a retracted local revision does not win a conflict either", () => {
|
|
|
426
436
|
peer: [file("facts/a.md", "live", 1000)],
|
|
427
437
|
tombstonedFileSha256: [digest("retracted")],
|
|
428
438
|
},
|
|
429
|
-
{ conflictPolicy: "newest-wins" }
|
|
439
|
+
{ conflictPolicy: "newest-wins" }
|
|
430
440
|
);
|
|
431
441
|
assert.equal(entryFor(entries, "facts/a.md").action, "suppress");
|
|
432
442
|
});
|
|
@@ -443,7 +453,7 @@ test("a census record without a usable digest is rejected", () => {
|
|
|
443
453
|
peer: [],
|
|
444
454
|
}),
|
|
445
455
|
/64-character sha256 hex digest/,
|
|
446
|
-
`digest ${JSON.stringify(bad)} must be rejected
|
|
456
|
+
`digest ${JSON.stringify(bad)} must be rejected`
|
|
447
457
|
);
|
|
448
458
|
}
|
|
449
459
|
});
|
|
@@ -458,15 +468,12 @@ test("paths differing only by case are rejected across censuses", () => {
|
|
|
458
468
|
local: [file("Facts/A.md", "one")],
|
|
459
469
|
peer: [file("facts/a.md", "two")],
|
|
460
470
|
}),
|
|
461
|
-
/aliasing paths
|
|
471
|
+
/aliasing paths/
|
|
462
472
|
);
|
|
463
473
|
});
|
|
464
474
|
|
|
465
475
|
test("a missing namespace or a non-iterable census is rejected", () => {
|
|
466
|
-
assert.throws(
|
|
467
|
-
() => planNamespaceReconciliation({ namespace: "", local: [], peer: [] }),
|
|
468
|
-
ReconcilePlanInputError,
|
|
469
|
-
);
|
|
476
|
+
assert.throws(() => planNamespaceReconciliation({ namespace: "", local: [], peer: [] }), ReconcilePlanInputError);
|
|
470
477
|
for (const side of ["local", "peer"] as const) {
|
|
471
478
|
assert.throws(
|
|
472
479
|
() =>
|
|
@@ -476,7 +483,7 @@ test("a missing namespace or a non-iterable census is rejected", () => {
|
|
|
476
483
|
peer: side === "peer" ? (undefined as unknown as ReconcileFileState[]) : [],
|
|
477
484
|
}),
|
|
478
485
|
/must be iterable/,
|
|
479
|
-
`${side} census
|
|
486
|
+
`${side} census`
|
|
480
487
|
);
|
|
481
488
|
}
|
|
482
489
|
});
|
|
@@ -540,7 +547,7 @@ test("a single digest string is rejected instead of being split into characters"
|
|
|
540
547
|
// Satisfies Iterable<string>; new Set() would make 64 one-char members.
|
|
541
548
|
tombstonedFileSha256: digest("gone") as unknown as string[],
|
|
542
549
|
}),
|
|
543
|
-
/must be a collection of digests, not a single string
|
|
550
|
+
/must be a collection of digests, not a single string/
|
|
544
551
|
);
|
|
545
552
|
assert.throws(
|
|
546
553
|
() =>
|
|
@@ -550,7 +557,7 @@ test("a single digest string is rejected instead of being split into characters"
|
|
|
550
557
|
peer: [file("facts/r.md", "gone")],
|
|
551
558
|
tombstonedFileSha256: ["not-a-digest"],
|
|
552
559
|
}),
|
|
553
|
-
/64-character sha256 hex digest
|
|
560
|
+
/64-character sha256 hex digest/
|
|
554
561
|
);
|
|
555
562
|
});
|
|
556
563
|
|
|
@@ -564,7 +571,7 @@ test("an unsafe census path is rejected before it becomes transfer work", () =>
|
|
|
564
571
|
peer: [{ path: bad, sha256: digest("x") }],
|
|
565
572
|
}),
|
|
566
573
|
ReconcilePlanInputError,
|
|
567
|
-
`peer census path ${bad} must be rejected
|
|
574
|
+
`peer census path ${bad} must be rejected`
|
|
568
575
|
);
|
|
569
576
|
}
|
|
570
577
|
});
|
|
@@ -579,7 +586,7 @@ test("a duplicate record disagreeing only on mtime is rejected", () => {
|
|
|
579
586
|
local: [],
|
|
580
587
|
peer: [file("facts/a.md", "same", 1000), file("facts/a.md", "same", 2000)],
|
|
581
588
|
}),
|
|
582
|
-
/lists facts\/a\.md twice with different mtimeMs
|
|
589
|
+
/lists facts\/a\.md twice with different mtimeMs/
|
|
583
590
|
);
|
|
584
591
|
});
|
|
585
592
|
|
|
@@ -592,7 +599,7 @@ test("the base census participates in case-collision detection", () => {
|
|
|
592
599
|
peer: [],
|
|
593
600
|
base: [file("Facts/A.md", "one")],
|
|
594
601
|
}),
|
|
595
|
-
/aliasing paths
|
|
602
|
+
/aliasing paths/
|
|
596
603
|
);
|
|
597
604
|
});
|
|
598
605
|
|
|
@@ -604,7 +611,7 @@ test("the streamed local census rejects an mtime-only duplicate like the indexed
|
|
|
604
611
|
local: [file("facts/a.md", "same", 1000), file("facts/a.md", "same", 2000)],
|
|
605
612
|
peer: [],
|
|
606
613
|
}),
|
|
607
|
-
/local census for namespace default lists facts\/a\.md twice with different mtimeMs
|
|
614
|
+
/local census for namespace default lists facts\/a\.md twice with different mtimeMs/
|
|
608
615
|
);
|
|
609
616
|
});
|
|
610
617
|
|
|
@@ -619,9 +626,9 @@ test("newest-wins cannot be flipped by local census ordering", () => {
|
|
|
619
626
|
() =>
|
|
620
627
|
planNamespaceReconciliation(
|
|
621
628
|
{ namespace: "default", local: order, peer: [file("facts/a.md", "peer", 5000)] },
|
|
622
|
-
{ conflictPolicy: "newest-wins" }
|
|
629
|
+
{ conflictPolicy: "newest-wins" }
|
|
623
630
|
),
|
|
624
|
-
ReconcilePlanInputError
|
|
631
|
+
ReconcilePlanInputError
|
|
625
632
|
);
|
|
626
633
|
}
|
|
627
634
|
});
|
|
@@ -635,7 +642,7 @@ test("the same namespace supplied twice is rejected", () => {
|
|
|
635
642
|
{ namespace: "default", local: [file("facts/a.md", "one")], peer: [] },
|
|
636
643
|
{ namespace: "default", local: [], peer: [file("facts/a.md", "two")] },
|
|
637
644
|
]),
|
|
638
|
-
/namespace default appears twice
|
|
645
|
+
/namespace default appears twice/
|
|
639
646
|
);
|
|
640
647
|
});
|
|
641
648
|
|
|
@@ -654,7 +661,7 @@ test("an out-of-range mtimeMs cannot decide newest-wins", () => {
|
|
|
654
661
|
base: side === "base" ? [record] : undefined,
|
|
655
662
|
}),
|
|
656
663
|
/out-of-range mtimeMs/,
|
|
657
|
-
`${side} census mtimeMs ${String(bad)} must be rejected
|
|
664
|
+
`${side} census mtimeMs ${String(bad)} must be rejected`
|
|
658
665
|
);
|
|
659
666
|
}
|
|
660
667
|
}
|
|
@@ -665,21 +672,21 @@ test("malformed public API envelopes raise ReconcilePlanInputError, not TypeErro
|
|
|
665
672
|
assert.throws(
|
|
666
673
|
() => planReconciliation(bad as unknown as []),
|
|
667
674
|
ReconcilePlanInputError,
|
|
668
|
-
`planReconciliation(${JSON.stringify(bad)})
|
|
675
|
+
`planReconciliation(${JSON.stringify(bad)})`
|
|
669
676
|
);
|
|
670
677
|
assert.throws(
|
|
671
678
|
() => planNamespaceReconciliation(bad as unknown as { namespace: string; local: []; peer: [] }),
|
|
672
679
|
ReconcilePlanInputError,
|
|
673
|
-
`planNamespaceReconciliation(${JSON.stringify(bad)})
|
|
680
|
+
`planNamespaceReconciliation(${JSON.stringify(bad)})`
|
|
674
681
|
);
|
|
675
682
|
}
|
|
676
683
|
assert.throws(
|
|
677
684
|
() =>
|
|
678
685
|
planNamespaceReconciliation(
|
|
679
686
|
{ namespace: "default", local: [], peer: [] },
|
|
680
|
-
null as unknown as Record<string, never
|
|
687
|
+
null as unknown as Record<string, never>
|
|
681
688
|
),
|
|
682
|
-
ReconcilePlanInputError
|
|
689
|
+
ReconcilePlanInputError
|
|
683
690
|
);
|
|
684
691
|
});
|
|
685
692
|
|
|
@@ -692,7 +699,7 @@ test("a fractional mtime from fs.stat is accepted", () => {
|
|
|
692
699
|
local: [file("facts/a.md", "local", 1_700_000_000_123.456)],
|
|
693
700
|
peer: [file("facts/a.md", "peer", 1_700_000_000_999.789)],
|
|
694
701
|
},
|
|
695
|
-
{ conflictPolicy: "newest-wins" }
|
|
702
|
+
{ conflictPolicy: "newest-wins" }
|
|
696
703
|
);
|
|
697
704
|
assert.equal(entryFor(entries, "facts/a.md").resolution, "peer-wins");
|
|
698
705
|
});
|
|
@@ -700,7 +707,7 @@ test("a fractional mtime from fs.stat is accepted", () => {
|
|
|
700
707
|
test("a non-canonical namespace is rejected so duplicates cannot slip past", () => {
|
|
701
708
|
assert.throws(
|
|
702
709
|
() => planNamespaceReconciliation({ namespace: " team ", local: [], peer: [] }),
|
|
703
|
-
/is not canonical; pass "team"
|
|
710
|
+
/is not canonical; pass "team"/
|
|
704
711
|
);
|
|
705
712
|
// The dedup guard would otherwise see two distinct keys for one namespace.
|
|
706
713
|
assert.throws(
|
|
@@ -709,7 +716,7 @@ test("a non-canonical namespace is rejected so duplicates cannot slip past", ()
|
|
|
709
716
|
{ namespace: "team", local: [file("facts/a.md", "one")], peer: [] },
|
|
710
717
|
{ namespace: " team ", local: [], peer: [file("facts/a.md", "two")] },
|
|
711
718
|
]),
|
|
712
|
-
ReconcilePlanInputError
|
|
719
|
+
ReconcilePlanInputError
|
|
713
720
|
);
|
|
714
721
|
});
|
|
715
722
|
|
|
@@ -723,7 +730,7 @@ test("a null base cursor is rejected rather than read as a bootstrap", () => {
|
|
|
723
730
|
peer: [],
|
|
724
731
|
base: null as unknown as undefined,
|
|
725
732
|
}),
|
|
726
|
-
/must be iterable
|
|
733
|
+
/must be iterable/
|
|
727
734
|
);
|
|
728
735
|
});
|
|
729
736
|
|
|
@@ -737,7 +744,7 @@ test("canonically equivalent Unicode paths are treated as one file", () => {
|
|
|
737
744
|
local: [file("facts/\u00e9.md", "one")],
|
|
738
745
|
peer: [file("facts/e\u0301.md", "two")],
|
|
739
746
|
}),
|
|
740
|
-
/aliasing paths
|
|
747
|
+
/aliasing paths/
|
|
741
748
|
);
|
|
742
749
|
});
|
|
743
750
|
|
|
@@ -746,13 +753,13 @@ test("an array is not a valid options or input envelope", () => {
|
|
|
746
753
|
() =>
|
|
747
754
|
planNamespaceReconciliation(
|
|
748
755
|
{ namespace: "default", local: [], peer: [] },
|
|
749
|
-
[] as unknown as Record<string, never
|
|
756
|
+
[] as unknown as Record<string, never>
|
|
750
757
|
),
|
|
751
|
-
/options must be a plain object
|
|
758
|
+
/options must be a plain object/
|
|
752
759
|
);
|
|
753
760
|
assert.throws(
|
|
754
761
|
() => planNamespaceReconciliation([] as unknown as { namespace: string; local: []; peer: [] }),
|
|
755
|
-
/namespace input must be a plain object
|
|
762
|
+
/namespace input must be a plain object/
|
|
756
763
|
);
|
|
757
764
|
});
|
|
758
765
|
|
|
@@ -781,7 +788,7 @@ test("the peer tombstone set is validated like our own", () => {
|
|
|
781
788
|
peer: [],
|
|
782
789
|
peerTombstonedFileSha256: digest("x") as unknown as string[],
|
|
783
790
|
}),
|
|
784
|
-
/peerTombstonedFileSha256 for namespace default must be a collection of digests
|
|
791
|
+
/peerTombstonedFileSha256 for namespace default must be a collection of digests/
|
|
785
792
|
);
|
|
786
793
|
});
|
|
787
794
|
|
|
@@ -791,18 +798,20 @@ test("Win32-aliasing path segments are rejected", () => {
|
|
|
791
798
|
for (const bad of ["facts/a.md.", "facts/a.md ", "facts/dir./a.md"]) {
|
|
792
799
|
assert.throws(
|
|
793
800
|
() =>
|
|
794
|
-
planNamespaceReconciliation(
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
801
|
+
planNamespaceReconciliation(
|
|
802
|
+
{
|
|
803
|
+
namespace: "default",
|
|
804
|
+
local: [{ path: bad, sha256: digest("x") }],
|
|
805
|
+
peer: [],
|
|
806
|
+
},
|
|
807
|
+
{ localPlatform: "win32" }
|
|
808
|
+
),
|
|
799
809
|
/dot or space/,
|
|
800
|
-
`path ${JSON.stringify(bad)} must be rejected
|
|
810
|
+
`path ${JSON.stringify(bad)} must be rejected`
|
|
801
811
|
);
|
|
802
812
|
}
|
|
803
813
|
});
|
|
804
814
|
|
|
805
|
-
|
|
806
815
|
test("an unorderable supersede link says so instead of picking a side", () => {
|
|
807
816
|
for (const pair of [
|
|
808
817
|
[file("facts/a.md", "local", 5000), file("facts/a.md", "peer", 5000)],
|
|
@@ -810,7 +819,7 @@ test("an unorderable supersede link says so instead of picking a side", () => {
|
|
|
810
819
|
] as const) {
|
|
811
820
|
const entries = planNamespaceReconciliation(
|
|
812
821
|
{ namespace: "default", local: [pair[0]], peer: [pair[1]] },
|
|
813
|
-
{ conflictPolicy: "newest-wins" }
|
|
822
|
+
{ conflictPolicy: "newest-wins" }
|
|
814
823
|
);
|
|
815
824
|
const entry = entryFor(entries, "facts/a.md");
|
|
816
825
|
assert.equal(entry.resolution, "supersede-link");
|
|
@@ -821,13 +830,16 @@ test("Windows-unstorable and reserved path names are rejected", () => {
|
|
|
821
830
|
for (const bad of ["facts/a:b.md", "facts/CON.md", "facts/com1.txt", 'facts/a"b.md', "facts/a\u0001b.md"]) {
|
|
822
831
|
assert.throws(
|
|
823
832
|
() =>
|
|
824
|
-
planNamespaceReconciliation(
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
833
|
+
planNamespaceReconciliation(
|
|
834
|
+
{
|
|
835
|
+
namespace: "default",
|
|
836
|
+
local: [{ path: bad, sha256: digest("x") }],
|
|
837
|
+
peer: [],
|
|
838
|
+
},
|
|
839
|
+
{ localPlatform: "win32" }
|
|
840
|
+
),
|
|
829
841
|
ReconcilePlanInputError,
|
|
830
|
-
`path ${JSON.stringify(bad)} must be rejected
|
|
842
|
+
`path ${JSON.stringify(bad)} must be rejected`
|
|
831
843
|
);
|
|
832
844
|
}
|
|
833
845
|
// A name that merely CONTAINS a reserved word is fine.
|
|
@@ -836,7 +848,7 @@ test("Windows-unstorable and reserved path names are rejected", () => {
|
|
|
836
848
|
namespace: "default",
|
|
837
849
|
local: [file("facts/console.md", "x")],
|
|
838
850
|
peer: [],
|
|
839
|
-
})
|
|
851
|
+
})
|
|
840
852
|
);
|
|
841
853
|
});
|
|
842
854
|
|
|
@@ -849,25 +861,27 @@ test("a directionless supersede link is reported as unresolved", () => {
|
|
|
849
861
|
local: [file("facts/a.md", "local", 5000)],
|
|
850
862
|
peer: [file("facts/a.md", "peer", 5000)],
|
|
851
863
|
},
|
|
852
|
-
{ conflictPolicy: "newest-wins" }
|
|
864
|
+
{ conflictPolicy: "newest-wins" }
|
|
853
865
|
);
|
|
854
866
|
assert.deepEqual(summarizeReconcilePlan(entries), [
|
|
855
867
|
{ namespace: "default", pull: 0, push: 0, identical: 0, conflict: 1, suppress: 0, unresolved: 1 },
|
|
856
868
|
]);
|
|
857
869
|
});
|
|
858
870
|
|
|
859
|
-
|
|
860
871
|
test("superscript COM and LPT device aliases are rejected", () => {
|
|
861
872
|
for (const bad of ["facts/COM\u00b9.txt", "facts/LPT\u00b2", "facts/com\u00b3.md"]) {
|
|
862
873
|
assert.throws(
|
|
863
874
|
() =>
|
|
864
|
-
planNamespaceReconciliation(
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
875
|
+
planNamespaceReconciliation(
|
|
876
|
+
{
|
|
877
|
+
namespace: "default",
|
|
878
|
+
local: [{ path: bad, sha256: digest("x") }],
|
|
879
|
+
peer: [],
|
|
880
|
+
},
|
|
881
|
+
{ localPlatform: "win32" }
|
|
882
|
+
),
|
|
869
883
|
/reserved Windows device name/,
|
|
870
|
-
`path ${JSON.stringify(bad)} must be rejected
|
|
884
|
+
`path ${JSON.stringify(bad)} must be rejected`
|
|
871
885
|
);
|
|
872
886
|
}
|
|
873
887
|
});
|
|
@@ -882,7 +896,7 @@ test("a full caseless fold catches sigma-style aliases", () => {
|
|
|
882
896
|
local: [file("facts/\u03c2.md", "one")],
|
|
883
897
|
peer: [file("facts/\u03c3.md", "two")],
|
|
884
898
|
}),
|
|
885
|
-
/aliasing paths
|
|
899
|
+
/aliasing paths/
|
|
886
900
|
);
|
|
887
901
|
});
|
|
888
902
|
|
|
@@ -894,18 +908,18 @@ test("non-plain objects are not accepted as envelopes", () => {
|
|
|
894
908
|
() =>
|
|
895
909
|
planNamespaceReconciliation(
|
|
896
910
|
{ namespace: "default", local: [], peer: [] },
|
|
897
|
-
bad as unknown as Record<string, never
|
|
911
|
+
bad as unknown as Record<string, never>
|
|
898
912
|
),
|
|
899
913
|
/options must be a plain object/,
|
|
900
|
-
`options ${Object.prototype.toString.call(bad)}
|
|
914
|
+
`options ${Object.prototype.toString.call(bad)}`
|
|
901
915
|
);
|
|
902
916
|
}
|
|
903
917
|
// A null-prototype record is still a record.
|
|
904
918
|
assert.doesNotThrow(() =>
|
|
905
919
|
planNamespaceReconciliation(
|
|
906
920
|
{ namespace: "default", local: [], peer: [] },
|
|
907
|
-
Object.assign(Object.create(null), { conflictPolicy: "manual" }) as Record<string, never
|
|
908
|
-
)
|
|
921
|
+
Object.assign(Object.create(null), { conflictPolicy: "manual" }) as Record<string, never>
|
|
922
|
+
)
|
|
909
923
|
);
|
|
910
924
|
});
|
|
911
925
|
|
|
@@ -915,7 +929,7 @@ test("an empty namespace list still validates its options", () => {
|
|
|
915
929
|
assert.throws(
|
|
916
930
|
() => planReconciliation([], bad as unknown as Record<string, never>),
|
|
917
931
|
ReconcilePlanInputError,
|
|
918
|
-
`options ${Object.prototype.toString.call(bad)}
|
|
932
|
+
`options ${Object.prototype.toString.call(bad)}`
|
|
919
933
|
);
|
|
920
934
|
}
|
|
921
935
|
assert.equal(planReconciliation([], { conflictPolicy: "manual" }).converged, true);
|
|
@@ -929,7 +943,7 @@ test("sharp-S aliases fold together", () => {
|
|
|
929
943
|
local: [file("facts/stra\u00dfe.md", "one")],
|
|
930
944
|
peer: [file("facts/stra\u1e9ee.md", "two")],
|
|
931
945
|
}),
|
|
932
|
-
/aliasing paths
|
|
946
|
+
/aliasing paths/
|
|
933
947
|
);
|
|
934
948
|
});
|
|
935
949
|
|
|
@@ -944,7 +958,7 @@ test("a malformed tombstone collection raises the planner's error, not a TypeErr
|
|
|
944
958
|
tombstonedFileSha256: bad as unknown as string[],
|
|
945
959
|
}),
|
|
946
960
|
ReconcilePlanInputError,
|
|
947
|
-
`tombstonedFileSha256 ${JSON.stringify(bad)}
|
|
961
|
+
`tombstonedFileSha256 ${JSON.stringify(bad)}`
|
|
948
962
|
);
|
|
949
963
|
}
|
|
950
964
|
});
|
|
@@ -955,12 +969,15 @@ test("an unpaired surrogate path is rejected", () => {
|
|
|
955
969
|
for (const bad of ["facts/\ud800.md", "facts/\udc00.md"]) {
|
|
956
970
|
assert.throws(
|
|
957
971
|
() =>
|
|
958
|
-
planNamespaceReconciliation(
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
972
|
+
planNamespaceReconciliation(
|
|
973
|
+
{
|
|
974
|
+
namespace: "default",
|
|
975
|
+
local: [{ path: bad, sha256: digest("x") }],
|
|
976
|
+
peer: [],
|
|
977
|
+
},
|
|
978
|
+
{ localPlatform: "win32" }
|
|
979
|
+
),
|
|
980
|
+
/unpaired surrogate/
|
|
964
981
|
);
|
|
965
982
|
}
|
|
966
983
|
// A well-formed pair is fine.
|
|
@@ -969,7 +986,7 @@ test("an unpaired surrogate path is rejected", () => {
|
|
|
969
986
|
namespace: "default",
|
|
970
987
|
local: [file("facts/\ud83d\ude00.md", "x")],
|
|
971
988
|
peer: [],
|
|
972
|
-
})
|
|
989
|
+
})
|
|
973
990
|
);
|
|
974
991
|
});
|
|
975
992
|
|
|
@@ -982,7 +999,7 @@ test("the base cursor is validated with the same rules as the other censuses", (
|
|
|
982
999
|
peer: [],
|
|
983
1000
|
base: [file("facts/a.md", "one"), file("facts/a.md", "two")],
|
|
984
1001
|
}),
|
|
985
|
-
/base census for namespace default lists facts\/a\.md twice with different digests
|
|
1002
|
+
/base census for namespace default lists facts\/a\.md twice with different digests/
|
|
986
1003
|
);
|
|
987
1004
|
// And it still drives the one-sided-change decision it exists for.
|
|
988
1005
|
const entries = planNamespaceReconciliation({
|
|
@@ -998,8 +1015,21 @@ test("the base cursor is validated with the same rules as the other censuses", (
|
|
|
998
1015
|
test("a namespace with an unpaired surrogate is rejected", () => {
|
|
999
1016
|
// namespaceIdentityToken() encodes through TextEncoder, so this and a
|
|
1000
1017
|
// literal U+FFFD namespace are one directory on disk.
|
|
1018
|
+
assert.throws(() => planNamespaceReconciliation({ namespace: "\ud800", local: [], peer: [] }), /unpaired surrogate/);
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
test("POSIX-origin colon paths are rejected when the PEER platform is win32", () => {
|
|
1001
1022
|
assert.throws(
|
|
1002
|
-
() =>
|
|
1003
|
-
|
|
1023
|
+
() =>
|
|
1024
|
+
planNamespaceReconciliation(
|
|
1025
|
+
{
|
|
1026
|
+
namespace: "default",
|
|
1027
|
+
local: [{ path: "facts/a:b.md", sha256: digest("x") }],
|
|
1028
|
+
peer: [],
|
|
1029
|
+
},
|
|
1030
|
+
{ peerPlatform: "win32" }
|
|
1031
|
+
),
|
|
1032
|
+
/character Windows cannot store/,
|
|
1033
|
+
"a push to a Windows peer must not plan a colon path"
|
|
1004
1034
|
);
|
|
1005
1035
|
});
|