memorymaster 3.26.0__tar.gz → 3.26.1__tar.gz

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.
Files changed (413) hide show
  1. {memorymaster-3.26.0/memorymaster.egg-info → memorymaster-3.26.1}/PKG-INFO +2 -2
  2. {memorymaster-3.26.0 → memorymaster-3.26.1}/README.md +1 -1
  3. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/__init__.py +1 -1
  4. {memorymaster-3.26.0 → memorymaster-3.26.1/memorymaster.egg-info}/PKG-INFO +2 -2
  5. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster.egg-info/SOURCES.txt +3 -0
  6. {memorymaster-3.26.0 → memorymaster-3.26.1}/pyproject.toml +1 -1
  7. memorymaster-3.26.1/tests/test_conflict_resolver_extra.py +415 -0
  8. memorymaster-3.26.1/tests/test_delta_sync_extra.py +392 -0
  9. memorymaster-3.26.1/tests/test_lifecycle_extra.py +314 -0
  10. {memorymaster-3.26.0 → memorymaster-3.26.1}/LICENSE +0 -0
  11. {memorymaster-3.26.0 → memorymaster-3.26.1}/artifacts/bm25-per-field-eval-harness.py +0 -0
  12. {memorymaster-3.26.0 → memorymaster-3.26.1}/benchmarks/longmemeval_runner.py +0 -0
  13. {memorymaster-3.26.0 → memorymaster-3.26.1}/benchmarks/longmemeval_vector_runner.py +0 -0
  14. {memorymaster-3.26.0 → memorymaster-3.26.1}/benchmarks/perf_smoke.py +0 -0
  15. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/__main__.py +0 -0
  16. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/_storage_lifecycle.py +0 -0
  17. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/_storage_read.py +0 -0
  18. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/_storage_schema.py +0 -0
  19. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/_storage_shared.py +0 -0
  20. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/_storage_sources.py +0 -0
  21. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/_storage_write_claims.py +0 -0
  22. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/access_control.py +0 -0
  23. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/action_exporters.py +0 -0
  24. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/action_extractor.py +0 -0
  25. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/atlas_claim_extractor.py +0 -0
  26. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/atlas_contract.py +0 -0
  27. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/auto_extractor.py +0 -0
  28. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/auto_resolver.py +0 -0
  29. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/candidate_dedupe.py +0 -0
  30. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/claim_edges.py +0 -0
  31. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/claim_verifier.py +0 -0
  32. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/cli.py +0 -0
  33. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/cli_handlers_basic.py +0 -0
  34. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/cli_handlers_curation.py +0 -0
  35. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/cli_helpers.py +0 -0
  36. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/closets.py +0 -0
  37. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config.py +0 -0
  38. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/claude-md-append.md +0 -0
  39. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/codex-agents-md-append.md +0 -0
  40. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-auto-ingest.py +0 -0
  41. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-classify.py +0 -0
  42. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-dream-sync.py +0 -0
  43. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-precompact.py +0 -0
  44. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-recall.py +0 -0
  45. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-session-start.py +0 -0
  46. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-steward-cycle.py +0 -0
  47. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-validate-wiki.py +0 -0
  48. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/conflict_resolver.py +0 -0
  49. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/connectors/__init__.py +0 -0
  50. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/connectors/whatsapp.py +0 -0
  51. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/context_hook.py +0 -0
  52. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/context_optimizer.py +0 -0
  53. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/contradiction_probe.py +0 -0
  54. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/daily_notes.py +0 -0
  55. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/dashboard.py +0 -0
  56. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/dashboard_auth.py +0 -0
  57. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/db_merge.py +0 -0
  58. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/delta_sync.py +0 -0
  59. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/dream_bridge.py +0 -0
  60. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/embeddings.py +0 -0
  61. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/entity_extractor.py +0 -0
  62. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/entity_graph.py +0 -0
  63. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/entity_registry.py +0 -0
  64. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/federated_graphify.py +0 -0
  65. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/feedback.py +0 -0
  66. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/graph_store.py +0 -0
  67. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/hook_log.py +0 -0
  68. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/__init__.py +0 -0
  69. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/calibration.py +0 -0
  70. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/compact_summaries.py +0 -0
  71. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/compactor.py +0 -0
  72. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/daydream_ingest.py +0 -0
  73. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/decay.py +0 -0
  74. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/dedup.py +0 -0
  75. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/deterministic.py +0 -0
  76. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/entity_graph_export.py +0 -0
  77. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/extractor.py +0 -0
  78. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/staleness.py +0 -0
  79. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/jobs/validator.py +0 -0
  80. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/key_rotator.py +0 -0
  81. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/lifecycle.py +0 -0
  82. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/llm_budget.py +0 -0
  83. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/llm_provider.py +0 -0
  84. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/llm_rerank.py +0 -0
  85. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/llm_steward.py +0 -0
  86. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/mcp_path_policy.py +0 -0
  87. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/mcp_server.py +0 -0
  88. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/mcp_usage.py +0 -0
  89. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/media_processing.py +0 -0
  90. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/media_providers.py +0 -0
  91. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/metrics_exporter.py +0 -0
  92. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/migrations/0001_initial.py +0 -0
  93. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/migrations/0002_miner_state.py +0 -0
  94. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/migrations/0003_contradiction_verdicts.py +0 -0
  95. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/migrations/0004_query_cache.py +0 -0
  96. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/migrations/__init__.py +0 -0
  97. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/migrations/runner.py +0 -0
  98. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/models.py +0 -0
  99. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/observability.py +0 -0
  100. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/operator.py +0 -0
  101. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/operator_queue.py +0 -0
  102. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/plugins.py +0 -0
  103. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/policy.py +0 -0
  104. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/postgres_store.py +0 -0
  105. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/qdrant_backend.py +0 -0
  106. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/qdrant_recall_fallback.py +0 -0
  107. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/qmd_bridge.py +0 -0
  108. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/query_cache.py +0 -0
  109. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/query_classifier.py +0 -0
  110. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/query_expansion.py +0 -0
  111. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/recall_fusion.py +0 -0
  112. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/recall_tokenizer.py +0 -0
  113. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/retrieval.py +0 -0
  114. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/retry.py +0 -0
  115. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/review.py +0 -0
  116. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/rl_trainer.py +0 -0
  117. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/rule_miner.py +0 -0
  118. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/rules.py +0 -0
  119. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/scheduler.py +0 -0
  120. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/schema.py +0 -0
  121. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/schema.sql +0 -0
  122. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/schema_postgres.sql +0 -0
  123. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/scope_utils.py +0 -0
  124. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/security.py +0 -0
  125. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/service.py +0 -0
  126. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/session_tracker.py +0 -0
  127. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/setup_hooks.py +0 -0
  128. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/skill_evolver.py +0 -0
  129. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/snapshot.py +0 -0
  130. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/steward.py +0 -0
  131. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/steward_classifier.py +0 -0
  132. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/steward_features.py +0 -0
  133. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/storage.py +0 -0
  134. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/store_factory.py +0 -0
  135. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/transcript_miner.py +0 -0
  136. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/turn_schema.py +0 -0
  137. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/vault_bases.py +0 -0
  138. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/vault_curator.py +0 -0
  139. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/vault_exporter.py +0 -0
  140. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/vault_linter.py +0 -0
  141. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/vault_log.py +0 -0
  142. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/vault_query_capture.py +0 -0
  143. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/vault_synthesis.py +0 -0
  144. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/verbatim_cleanup.py +0 -0
  145. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/verbatim_recall.py +0 -0
  146. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/verbatim_store.py +0 -0
  147. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/webhook.py +0 -0
  148. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/wiki_engine.py +0 -0
  149. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/wiki_freshness.py +0 -0
  150. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/wiki_similarity.py +0 -0
  151. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/wiki_suggest.py +0 -0
  152. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster/wiki_validate.py +0 -0
  153. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster.egg-info/dependency_links.txt +0 -0
  154. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster.egg-info/entry_points.txt +0 -0
  155. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster.egg-info/requires.txt +0 -0
  156. {memorymaster-3.26.0 → memorymaster-3.26.1}/memorymaster.egg-info/top_level.txt +0 -0
  157. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/agg_recall_latency.py +0 -0
  158. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/alert_operator_metrics.py +0 -0
  159. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/audit_dedupe_precision.py +0 -0
  160. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/autoresearch_daemon.py +0 -0
  161. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/backfill_entity_extraction.py +0 -0
  162. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/backfill_graph_store.py +0 -0
  163. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/backfill_stop_hook_citations.py +0 -0
  164. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/backtest_steward_classifier.py +0 -0
  165. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/build_steward_training_set.py +0 -0
  166. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/check_hook_template_drift.py +0 -0
  167. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/claude_to_turns.py +0 -0
  168. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/codex_live_to_turns.py +0 -0
  169. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/compaction_edge_cases.py +0 -0
  170. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/compaction_trace_report.py +0 -0
  171. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/compaction_trace_validate.py +0 -0
  172. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/confusion_matrix_eval.py +0 -0
  173. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/conversation_importer.py +0 -0
  174. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/conversation_to_turns.py +0 -0
  175. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/e2e_operator.py +0 -0
  176. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/email_live_to_turns.py +0 -0
  177. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/eval_bm25_sweep.py +0 -0
  178. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/eval_classify_f1.py +0 -0
  179. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/eval_memorymaster.py +0 -0
  180. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/eval_recall_precision_at_5.py +0 -0
  181. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/eval_recall_quality.py +0 -0
  182. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/eval_steward_pareto.py +0 -0
  183. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/eval_verbatim_recall.py +0 -0
  184. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/expand_recall_eval.py +0 -0
  185. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/generate_drill_signoff.py +0 -0
  186. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/git_to_turns.py +0 -0
  187. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/github_live_to_turns.py +0 -0
  188. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/gitnexus_to_claims.py +0 -0
  189. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/grid_recall_weights.py +0 -0
  190. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/index_claims_to_qdrant.py +0 -0
  191. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/ingest_planning_docs.py +0 -0
  192. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/jira_live_to_turns.py +0 -0
  193. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/label_prompts_with_judge.py +0 -0
  194. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/llm_benchmark.py +0 -0
  195. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/measure_dedupe_thresholds.py +0 -0
  196. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/merge_scope_variants.py +0 -0
  197. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/messages_to_turns.py +0 -0
  198. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/operator_metrics.py +0 -0
  199. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/precompute_candidates.py +0 -0
  200. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/recurring_incident_drill.py +0 -0
  201. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/release_readiness.py +0 -0
  202. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/run_codex_autologger.py +0 -0
  203. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/run_incident_drill.py +0 -0
  204. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/scheduled_ingest.py +0 -0
  205. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/setup-hooks.py +0 -0
  206. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/slack_live_to_turns.py +0 -0
  207. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/sync_hook_templates.py +0 -0
  208. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/tickets_to_turns.py +0 -0
  209. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/train_steward_classifier.py +0 -0
  210. {memorymaster-3.26.0 → memorymaster-3.26.1}/scripts/webhook_to_turns.py +0 -0
  211. {memorymaster-3.26.0 → memorymaster-3.26.1}/setup.cfg +0 -0
  212. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/bench_longmemeval.py +0 -0
  213. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/conftest.py +0 -0
  214. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/integration/test_extract_llm_ollama_live.py +0 -0
  215. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_access_control.py +0 -0
  216. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_action_exporters.py +0 -0
  217. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_action_extractor.py +0 -0
  218. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_atlas_claim_extractor.py +0 -0
  219. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_atlas_contract.py +0 -0
  220. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_atlas_source_schema.py +0 -0
  221. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_auto_extractor.py +0 -0
  222. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_auto_ingest_hook_citations.py +0 -0
  223. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_auto_ingest_hook_schema.py +0 -0
  224. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_auto_resolver.py +0 -0
  225. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_auto_validate.py +0 -0
  226. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_backend_parity.py +0 -0
  227. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_bench_answer_prompt.py +0 -0
  228. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_bm25_per_field.py +0 -0
  229. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_calibration.py +0 -0
  230. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_calibration_priors_applied.py +0 -0
  231. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_candidate_dedupe.py +0 -0
  232. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_claim_edges.py +0 -0
  233. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_claim_links.py +0 -0
  234. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_claim_type_ranking.py +0 -0
  235. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_classify_hook_f1.py +0 -0
  236. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_classify_hook_latency.py +0 -0
  237. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_claude_to_turns.py +0 -0
  238. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_cli_dry_run.py +0 -0
  239. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_cli_handlers_extra.py +0 -0
  240. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_cli_json_flag.py +0 -0
  241. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_cli_ready.py +0 -0
  242. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_cli_review_queue.py +0 -0
  243. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_cli_subcommands.py +0 -0
  244. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_closets.py +0 -0
  245. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_closets_recall_integration.py +0 -0
  246. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_compact_summaries.py +0 -0
  247. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_compact_summaries_sensitivity.py +0 -0
  248. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_compaction_trace.py +0 -0
  249. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_compactor_artifact_order.py +0 -0
  250. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_config.py +0 -0
  251. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_conflict_resolver.py +0 -0
  252. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_confusion_matrix_eval.py +0 -0
  253. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_connection_retry.py +0 -0
  254. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_connectors.py +0 -0
  255. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_context_hook.py +0 -0
  256. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_context_hook_extra.py +0 -0
  257. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_context_optimizer.py +0 -0
  258. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_context_optimizer_provider.py +0 -0
  259. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_contradiction_probe.py +0 -0
  260. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_conversation_to_turns.py +0 -0
  261. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dashboard.py +0 -0
  262. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dashboard_auth.py +0 -0
  263. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dashboard_coverage.py +0 -0
  264. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dashboard_latency.py +0 -0
  265. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dashboard_lineage.py +0 -0
  266. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dashboard_review_queue.py +0 -0
  267. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_daydream_ingest.py +0 -0
  268. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_db_merge_confidence_conflict.py +0 -0
  269. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_db_merge_coverage_v2.py +0 -0
  270. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_db_merge_extra.py +0 -0
  271. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_decay_coverage.py +0 -0
  272. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_decay_respects_pinned.py +0 -0
  273. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dedup.py +0 -0
  274. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dedup_cli.py +0 -0
  275. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dedup_conflict_disambiguation.py +0 -0
  276. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_delta_sync.py +0 -0
  277. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_deterministic_predicates.py +0 -0
  278. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dream_bridge_coverage_v2.py +0 -0
  279. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dream_bridge_extra.py +0 -0
  280. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_dream_bridge_sensitivity.py +0 -0
  281. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_embeddings_coverage.py +0 -0
  282. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_entity_extractor.py +0 -0
  283. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_entity_extractor_llm.py +0 -0
  284. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_entity_graph.py +0 -0
  285. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_entity_graph_export.py +0 -0
  286. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_entity_new_kinds.py +0 -0
  287. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_entity_regex_v3.py +0 -0
  288. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_entity_registry.py +0 -0
  289. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_entity_registry_extra.py +0 -0
  290. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_eval_harness.py +0 -0
  291. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_events_schema.py +0 -0
  292. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_extract_llm_ollama.py +0 -0
  293. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_federated_graphify_mcp.py +0 -0
  294. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_federated_query_safety.py +0 -0
  295. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_feedback.py +0 -0
  296. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_floor_gate.py +0 -0
  297. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_fts5_search.py +0 -0
  298. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_graph_distance.py +0 -0
  299. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_graph_store.py +0 -0
  300. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_handler_regressions.py +0 -0
  301. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_hook_env_isolation.py +0 -0
  302. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_human_id.py +0 -0
  303. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_incident_drill_runner.py +0 -0
  304. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_integration_workflows.py +0 -0
  305. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_key_rotator.py +0 -0
  306. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_lifecycle.py +0 -0
  307. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_lifecycle_supersede_invariant.py +0 -0
  308. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_llm_budget.py +0 -0
  309. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_llm_fallback.py +0 -0
  310. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_llm_provider_claude_cli.py +0 -0
  311. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_llm_provider_extra.py +0 -0
  312. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_llm_provider_key_rotation.py +0 -0
  313. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_llm_steward_coverage.py +0 -0
  314. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_llm_steward_key_rotation.py +0 -0
  315. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_mcp_filter_bypass.py +0 -0
  316. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_mcp_helpers.py +0 -0
  317. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_mcp_path_policy.py +0 -0
  318. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_mcp_rate_limit.py +0 -0
  319. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_mcp_server_validation.py +0 -0
  320. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_mcp_usage.py +0 -0
  321. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_media_processing.py +0 -0
  322. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_meta_decisions.py +0 -0
  323. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_metrics_exporter.py +0 -0
  324. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_migrations.py +0 -0
  325. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_observability.py +0 -0
  326. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_observability_extra.py +0 -0
  327. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_obsidian_mind_patterns.py +0 -0
  328. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_operator.py +0 -0
  329. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_operator_queue.py +0 -0
  330. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_perf_smoke_config.py +0 -0
  331. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_plugins.py +0 -0
  332. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_policy_coverage.py +0 -0
  333. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_policy_mode_env.py +0 -0
  334. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_postgres_parity.py +0 -0
  335. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_qdrant_backend.py +0 -0
  336. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_qmd_bridge.py +0 -0
  337. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_qrels_regression.py +0 -0
  338. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_query_cache.py +0 -0
  339. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_query_classifier.py +0 -0
  340. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_query_expansion.py +0 -0
  341. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_recall_entity_fanout.py +0 -0
  342. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_recall_fusion.py +0 -0
  343. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_recall_latency.py +0 -0
  344. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_recall_precision_at_5.py +0 -0
  345. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_recall_tokenizer.py +0 -0
  346. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_recall_vector_fallback.py +0 -0
  347. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_reliability_hardening.py +0 -0
  348. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_resolvers_concurrent_supersede.py +0 -0
  349. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_retrieval_extra.py +0 -0
  350. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_retrieval_profile.py +0 -0
  351. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_retrieval_profiles.py +0 -0
  352. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_retrieval_rrf_tiebreaker.py +0 -0
  353. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_retrieval_weights.py +0 -0
  354. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_review.py +0 -0
  355. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_rl_trainer.py +0 -0
  356. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_rrf_auto_gate.py +0 -0
  357. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_rule_claims.py +0 -0
  358. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_rule_miner.py +0 -0
  359. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_scheduler.py +0 -0
  360. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_schema.py +0 -0
  361. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_scope_boost.py +0 -0
  362. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_scope_utils.py +0 -0
  363. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_security_access.py +0 -0
  364. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_security_patterns.py +0 -0
  365. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_sensitivity_filter_adversarial.py +0 -0
  366. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_sensitivity_filter_adversarial_v2.py +0 -0
  367. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_sensitivity_filter_t07.py +0 -0
  368. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_service_coverage.py +0 -0
  369. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_session_tracker.py +0 -0
  370. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_snapshot.py +0 -0
  371. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_snapshot_roundtrip.py +0 -0
  372. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_sqlite_core.py +0 -0
  373. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_staleness.py +0 -0
  374. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_stealth_mode.py +0 -0
  375. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_steward.py +0 -0
  376. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_steward_classifier.py +0 -0
  377. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_steward_contradiction_phase.py +0 -0
  378. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_steward_daydream_hook.py +0 -0
  379. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_steward_features.py +0 -0
  380. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_steward_features_v3.py +0 -0
  381. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_steward_resolution_parity.py +0 -0
  382. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_storage_extra.py +0 -0
  383. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_storage_parity.py +0 -0
  384. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_store_factory.py +0 -0
  385. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_tenant_isolation.py +0 -0
  386. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_turn_schema.py +0 -0
  387. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_two_pass_recall.py +0 -0
  388. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_v311_fixes.py +0 -0
  389. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_v313_e2e.py +0 -0
  390. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_v313_run_cycle_dedupe.py +0 -0
  391. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_v390_e2e.py +0 -0
  392. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_v391_strict_warnings.py +0 -0
  393. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_vault_exporter.py +0 -0
  394. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_vault_linter_extra.py +0 -0
  395. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_vault_linter_orphan.py +0 -0
  396. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_vector_search.py +0 -0
  397. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_verbatim_cleanup.py +0 -0
  398. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_verbatim_dedup.py +0 -0
  399. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_verbatim_recall.py +0 -0
  400. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_verbatim_store.py +0 -0
  401. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_verbatim_store_qdrant.py +0 -0
  402. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_webhook.py +0 -0
  403. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_webhook_hmac.py +0 -0
  404. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_whatsapp_importer.py +0 -0
  405. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_autopromote.py +0 -0
  406. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_binding.py +0 -0
  407. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_engine_extra.py +0 -0
  408. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_engine_idempotency.py +0 -0
  409. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_explored_and_contradictions.py +0 -0
  410. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_freshness.py +0 -0
  411. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_similarity_multiscope.py +0 -0
  412. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_suggest.py +0 -0
  413. {memorymaster-3.26.0 → memorymaster-3.26.1}/tests/test_wiki_validate_cli.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memorymaster
3
- Version: 3.26.0
3
+ Version: 3.26.1
4
4
  Summary: Production-grade memory reliability system for AI coding agents. Lifecycle-managed claims with citations, conflict detection, steward governance, and MCP integration.
5
5
  Author: wolverin0
6
6
  License: MIT
@@ -52,7 +52,7 @@ Lifecycle-managed claims with citations, conflict detection, steward governance,
52
52
 
53
53
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
54
54
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
55
- [![Tests](https://img.shields.io/badge/tests-2514-green.svg)]()
55
+ [![Tests](https://img.shields.io/badge/tests-2556-green.svg)]()
56
56
  [![MCP Tools](https://img.shields.io/badge/MCP%20tools-24-purple.svg)]()
57
57
  [![CLI Commands](https://img.shields.io/badge/CLI%20commands-86-orange.svg)]()
58
58
  [![PyPI](https://img.shields.io/pypi/v/memorymaster.svg)](https://pypi.org/project/memorymaster/)
@@ -6,7 +6,7 @@ Lifecycle-managed claims with citations, conflict detection, steward governance,
6
6
 
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
8
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
9
- [![Tests](https://img.shields.io/badge/tests-2514-green.svg)]()
9
+ [![Tests](https://img.shields.io/badge/tests-2556-green.svg)]()
10
10
  [![MCP Tools](https://img.shields.io/badge/MCP%20tools-24-purple.svg)]()
11
11
  [![CLI Commands](https://img.shields.io/badge/CLI%20commands-86-orange.svg)]()
12
12
  [![PyPI](https://img.shields.io/pypi/v/memorymaster.svg)](https://pypi.org/project/memorymaster/)
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "3.26.0"
5
+ __version__ = "3.26.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memorymaster
3
- Version: 3.26.0
3
+ Version: 3.26.1
4
4
  Summary: Production-grade memory reliability system for AI coding agents. Lifecycle-managed claims with citations, conflict detection, steward governance, and MCP integration.
5
5
  Author: wolverin0
6
6
  License: MIT
@@ -52,7 +52,7 @@ Lifecycle-managed claims with citations, conflict detection, steward governance,
52
52
 
53
53
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
54
54
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
55
- [![Tests](https://img.shields.io/badge/tests-2514-green.svg)]()
55
+ [![Tests](https://img.shields.io/badge/tests-2556-green.svg)]()
56
56
  [![MCP Tools](https://img.shields.io/badge/MCP%20tools-24-purple.svg)]()
57
57
  [![CLI Commands](https://img.shields.io/badge/CLI%20commands-86-orange.svg)]()
58
58
  [![PyPI](https://img.shields.io/pypi/v/memorymaster.svg)](https://pypi.org/project/memorymaster/)
@@ -243,6 +243,7 @@ tests/test_compaction_trace.py
243
243
  tests/test_compactor_artifact_order.py
244
244
  tests/test_config.py
245
245
  tests/test_conflict_resolver.py
246
+ tests/test_conflict_resolver_extra.py
246
247
  tests/test_confusion_matrix_eval.py
247
248
  tests/test_connection_retry.py
248
249
  tests/test_connectors.py
@@ -268,6 +269,7 @@ tests/test_dedup.py
268
269
  tests/test_dedup_cli.py
269
270
  tests/test_dedup_conflict_disambiguation.py
270
271
  tests/test_delta_sync.py
272
+ tests/test_delta_sync_extra.py
271
273
  tests/test_deterministic_predicates.py
272
274
  tests/test_dream_bridge_coverage_v2.py
273
275
  tests/test_dream_bridge_extra.py
@@ -298,6 +300,7 @@ tests/test_incident_drill_runner.py
298
300
  tests/test_integration_workflows.py
299
301
  tests/test_key_rotator.py
300
302
  tests/test_lifecycle.py
303
+ tests/test_lifecycle_extra.py
301
304
  tests/test_lifecycle_supersede_invariant.py
302
305
  tests/test_llm_budget.py
303
306
  tests/test_llm_fallback.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memorymaster"
7
- version = "3.26.0"
7
+ version = "3.26.1"
8
8
  description = "Production-grade memory reliability system for AI coding agents. Lifecycle-managed claims with citations, conflict detection, steward governance, and MCP integration."
9
9
  license = {text = "MIT"}
10
10
  authors = [{name = "wolverin0"}]
@@ -0,0 +1,415 @@
1
+ """Extra coverage for conflict resolution (deterministic + LLM-driven).
2
+
3
+ Covers three contracts that the rest of the system relies on:
4
+
5
+ 1. Winner selection between two conflicting claims (conflict_resolver._pick_winner)
6
+ follows the documented priority chain: pinned > confidence > recency >
7
+ citations > id. The *reason* string is the public contract — these tests
8
+ anchor on the rule that fired, not on which integer id happens to win.
9
+
10
+ 2. Supersession wiring is bidirectional: after resolution the winner carries
11
+ supersedes_claim_id pointing at the loser, and the loser carries
12
+ replaced_by_claim_id pointing at the winner AND status == 'superseded'.
13
+ A half-wired pair silently breaks the wiki, so both legs are asserted.
14
+
15
+ 3. The LLM-driven path (auto_resolver.resolve_conflict_pair) honours the
16
+ model's verdict for BOTH the chosen-winner branch and the
17
+ no-clear-winner / abstain branch — and never deletes the loser, only
18
+ supersedes it. The LLM call is monkeypatched; no real provider is hit.
19
+
20
+ All DBs are built fresh per-test from the project schema via MemoryService.
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ from pathlib import Path
26
+
27
+ from memorymaster.models import Claim, Citation, CitationInput
28
+ from memorymaster.service import MemoryService
29
+ from memorymaster.lifecycle import transition_claim
30
+ from memorymaster.conflict_resolver import (
31
+ _pick_winner,
32
+ supersede_claim,
33
+ resolve_conflicts,
34
+ SupersessionRaceLost,
35
+ )
36
+ from memorymaster import auto_resolver
37
+ from memorymaster.auto_resolver import resolve_conflict_pair, auto_resolve_conflicts
38
+
39
+
40
+ # --------------------------------------------------------------------------- #
41
+ # Helpers
42
+ # --------------------------------------------------------------------------- #
43
+ def _make_claim(
44
+ *,
45
+ id: int = 1,
46
+ subject: str | None = "server",
47
+ predicate: str | None = "port",
48
+ object_value: str | None = "8080",
49
+ scope: str = "project",
50
+ status: str = "confirmed",
51
+ confidence: float = 0.7,
52
+ pinned: bool = False,
53
+ updated_at: str = "2026-01-01T00:00:00+00:00",
54
+ citations: list | None = None,
55
+ ) -> Claim:
56
+ return Claim(
57
+ id=id,
58
+ text=f"{subject} {predicate} is {object_value}",
59
+ idempotency_key=None,
60
+ normalized_text=None,
61
+ claim_type=None,
62
+ subject=subject,
63
+ predicate=predicate,
64
+ object_value=object_value,
65
+ scope=scope,
66
+ volatility="medium",
67
+ status=status,
68
+ confidence=confidence,
69
+ pinned=pinned,
70
+ supersedes_claim_id=None,
71
+ replaced_by_claim_id=None,
72
+ created_at="2026-01-01T00:00:00+00:00",
73
+ updated_at=updated_at,
74
+ last_validated_at=None,
75
+ archived_at=None,
76
+ citations=citations or [],
77
+ )
78
+
79
+
80
+ def _fresh_service(tmp_path: Path) -> MemoryService:
81
+ svc = MemoryService(str(tmp_path / "test.db"))
82
+ svc.init_db()
83
+ return svc
84
+
85
+
86
+ def _cite() -> Citation:
87
+ return Citation(
88
+ id=1, claim_id=1, source="doc", locator=None,
89
+ excerpt=None, created_at="2026-01-01T00:00:00+00:00",
90
+ )
91
+
92
+
93
+ # --------------------------------------------------------------------------- #
94
+ # 1. Winner selection — anchored on the rule that fired, not the id
95
+ # --------------------------------------------------------------------------- #
96
+ class TestWinnerSelectionRules:
97
+ def test_pinned_overrides_a_higher_confidence_rival(self):
98
+ """Contract: a pinned claim must win even against a more-confident
99
+ unpinned rival. If this regresses, a manually-protected fact gets
100
+ auto-superseded by noise."""
101
+ pinned_low = _make_claim(id=1, confidence=0.10, pinned=True)
102
+ unpinned_high = _make_claim(id=2, confidence=0.99, pinned=False)
103
+ pair = _pick_winner(pinned_low, unpinned_high)
104
+ assert pair.reason == "pinned_wins"
105
+ assert pair.winner is pinned_low
106
+ assert pair.loser is unpinned_high
107
+
108
+ def test_confidence_decides_when_pin_state_is_equal(self):
109
+ """Contract: with pin state equal, the higher-confidence claim wins.
110
+ Confidence is the primary evidence signal."""
111
+ weak = _make_claim(id=10, confidence=0.40)
112
+ strong = _make_claim(id=11, confidence=0.80)
113
+ pair = _pick_winner(weak, strong)
114
+ assert pair.reason == "higher_confidence"
115
+ assert pair.winner is strong
116
+
117
+ def test_recency_breaks_a_confidence_tie(self):
118
+ """Contract: equal confidence -> the freshest updated_at wins. Newer
119
+ information supersedes older information of equal strength."""
120
+ old = _make_claim(id=20, confidence=0.7, updated_at="2026-01-01T00:00:00+00:00")
121
+ new = _make_claim(id=21, confidence=0.7, updated_at="2026-03-01T00:00:00+00:00")
122
+ pair = _pick_winner(old, new)
123
+ assert pair.reason == "more_recent"
124
+ assert pair.winner is new
125
+
126
+ def test_citation_count_breaks_a_confidence_and_recency_tie(self):
127
+ """Contract: equal confidence and equal timestamp -> more citations
128
+ wins. Better-evidenced claims are preferred."""
129
+ c = _cite()
130
+ few = _make_claim(id=30, confidence=0.7, citations=[c])
131
+ many = _make_claim(id=31, confidence=0.7, citations=[c, c, c])
132
+ pair = _pick_winner(few, many)
133
+ assert pair.reason == "more_citations"
134
+ assert pair.winner is many
135
+
136
+ def test_full_tie_falls_back_to_deterministic_id(self):
137
+ """Contract: when every signal ties, resolution must still be
138
+ deterministic (higher id = most recently created wins) so repeated
139
+ runs never flip the winner."""
140
+ a = _make_claim(id=40, confidence=0.7)
141
+ b = _make_claim(id=41, confidence=0.7)
142
+ first = _pick_winner(a, b)
143
+ # Argument order must not change the outcome — determinism.
144
+ second = _pick_winner(b, a)
145
+ assert first.reason == "higher_id_tiebreaker"
146
+ assert first.winner.id == 41
147
+ assert second.winner.id == 41
148
+
149
+
150
+ # --------------------------------------------------------------------------- #
151
+ # 2. Supersession wiring (deterministic resolve_conflicts, real DB)
152
+ # --------------------------------------------------------------------------- #
153
+ class TestSupersessionWiring:
154
+ def _two_conflicting(self, svc: MemoryService):
155
+ loser = svc.ingest(
156
+ text="server port is 8080",
157
+ citations=[CitationInput(source="doc1")],
158
+ subject="server", predicate="port", object_value="8080",
159
+ confidence=0.40,
160
+ )
161
+ winner = svc.ingest(
162
+ text="server port is 3000",
163
+ citations=[CitationInput(source="doc2")],
164
+ subject="server", predicate="port", object_value="3000",
165
+ confidence=0.95,
166
+ )
167
+ return loser, winner
168
+
169
+ def test_both_sides_of_the_link_are_set(self, tmp_path):
170
+ """Contract: a resolved conflict must wire BOTH legs — loser.replaced_by
171
+ -> winner and winner.supersedes -> loser — and flip the loser to
172
+ 'superseded'. A one-legged link corrupts the wiki's supersession graph."""
173
+ svc = _fresh_service(tmp_path)
174
+ loser, winner = self._two_conflicting(svc)
175
+
176
+ result = resolve_conflicts(svc, dry_run=False, statuses=["candidate"])
177
+ assert result.pairs_resolved >= 1
178
+
179
+ loser_fresh = svc.store.get_claim(loser.id)
180
+ winner_fresh = svc.store.get_claim(winner.id)
181
+
182
+ # Loser leg
183
+ assert loser_fresh.status == "superseded"
184
+ assert loser_fresh.replaced_by_claim_id == winner.id
185
+ # Winner leg
186
+ assert winner_fresh.supersedes_claim_id == loser.id
187
+ # Winner is NOT mutated into a terminal state
188
+ assert winner_fresh.status == "candidate"
189
+
190
+ def test_higher_confidence_claim_is_the_survivor(self, tmp_path):
191
+ """Contract: the survivor of an auto-resolution is the higher-confidence
192
+ claim, never the weaker one. Asserts on which *value* survived, not on
193
+ ids, so it stays valid if id assignment changes."""
194
+ svc = _fresh_service(tmp_path)
195
+ loser, winner = self._two_conflicting(svc)
196
+
197
+ resolve_conflicts(svc, dry_run=False, statuses=["candidate"])
198
+
199
+ loser_fresh = svc.store.get_claim(loser.id)
200
+ winner_fresh = svc.store.get_claim(winner.id)
201
+ assert winner_fresh.object_value == "3000" # the 0.95-confidence value
202
+ assert loser_fresh.object_value == "8080" # the 0.40-confidence value
203
+ assert loser_fresh.status == "superseded"
204
+ assert winner_fresh.status != "superseded"
205
+
206
+ def test_supersede_claim_is_idempotent_against_double_resolve(self, tmp_path):
207
+ """Contract: re-running resolution must not re-supersede an already
208
+ superseded loser — the second pass resolves nothing. Protects against
209
+ duplicate audit trails / link churn."""
210
+ svc = _fresh_service(tmp_path)
211
+ self._two_conflicting(svc)
212
+
213
+ first = resolve_conflicts(svc, dry_run=False, statuses=["candidate"])
214
+ assert first.pairs_resolved >= 1
215
+ second = resolve_conflicts(
216
+ svc, dry_run=False, statuses=["candidate", "superseded"]
217
+ )
218
+ assert second.pairs_resolved == 0
219
+
220
+
221
+ class TestSupersedeClaimPrimitive:
222
+ def test_supersede_claim_links_and_transitions_loser(self, tmp_path):
223
+ """Contract: supersede_claim() is the atomic primitive — it flips the
224
+ old claim to 'superseded' and stamps replaced_by, while the new claim
225
+ gains supersedes_claim_id. Directly exercises the SQLite atomic path."""
226
+ svc = _fresh_service(tmp_path)
227
+ old = svc.ingest(
228
+ text="old fact", citations=[CitationInput(source="d1")],
229
+ subject="x", predicate="y", object_value="a",
230
+ )
231
+ new = svc.ingest(
232
+ text="new fact", citations=[CitationInput(source="d2")],
233
+ subject="x", predicate="y", object_value="b",
234
+ )
235
+
236
+ updated_old = supersede_claim(
237
+ svc.store, old_claim_id=old.id, new_claim_id=new.id,
238
+ reason="test_supersede",
239
+ )
240
+ assert updated_old.status == "superseded"
241
+ assert updated_old.replaced_by_claim_id == new.id
242
+ new_fresh = svc.store.get_claim(new.id)
243
+ assert new_fresh.supersedes_claim_id == old.id
244
+
245
+ def test_supersede_claim_rejects_a_lost_race(self, tmp_path):
246
+ """Contract: if the old claim was already superseded by someone else,
247
+ supersede_claim must raise SupersessionRaceLost rather than silently
248
+ overwriting the existing replacement pointer."""
249
+ svc = _fresh_service(tmp_path)
250
+ old = svc.ingest(
251
+ text="old", citations=[CitationInput(source="d1")],
252
+ subject="x", predicate="y", object_value="a",
253
+ )
254
+ first = svc.ingest(
255
+ text="first replacement", citations=[CitationInput(source="d2")],
256
+ subject="x", predicate="y", object_value="b",
257
+ )
258
+ second = svc.ingest(
259
+ text="second replacement", citations=[CitationInput(source="d3")],
260
+ subject="x", predicate="y", object_value="c",
261
+ )
262
+ supersede_claim(svc.store, old_claim_id=old.id, new_claim_id=first.id, reason="r1")
263
+
264
+ raised = False
265
+ try:
266
+ supersede_claim(svc.store, old_claim_id=old.id, new_claim_id=second.id, reason="r2")
267
+ except SupersessionRaceLost as exc:
268
+ raised = True
269
+ assert exc.current_replacement_id == first.id
270
+ assert raised, "expected SupersessionRaceLost on a second supersede of the same claim"
271
+ # The original winner pointer must be untouched.
272
+ assert svc.store.get_claim(old.id).replaced_by_claim_id == first.id
273
+
274
+
275
+ # --------------------------------------------------------------------------- #
276
+ # 3. LLM-resolution path (auto_resolver) — monkeypatched, never real infra
277
+ # --------------------------------------------------------------------------- #
278
+ def _conflicted_pair(svc: MemoryService):
279
+ """Ingest two contradicting claims and move both into 'conflicted'."""
280
+ a = svc.ingest(
281
+ text="region is us-east", citations=[CitationInput(source="d1")],
282
+ subject="db", predicate="region", object_value="us-east", confidence=0.5,
283
+ )
284
+ b = svc.ingest(
285
+ text="region is eu-west", citations=[CitationInput(source="d2")],
286
+ subject="db", predicate="region", object_value="eu-west", confidence=0.5,
287
+ )
288
+ transition_claim(svc.store, claim_id=a.id, to_status="conflicted",
289
+ reason="seed", event_type="validator")
290
+ transition_claim(svc.store, claim_id=b.id, to_status="conflicted",
291
+ reason="seed", event_type="validator")
292
+ return (
293
+ svc.store.get_claim(a.id, include_citations=True),
294
+ svc.store.get_claim(b.id, include_citations=True),
295
+ )
296
+
297
+
298
+ class TestLlmResolutionPath:
299
+ def test_llm_picks_a_and_supersedes_b(self, tmp_path, monkeypatch):
300
+ """Contract: when the model votes 'A', claim A survives and claim B is
301
+ superseded with A as its replacement — the loser is preserved (audit
302
+ trail), never deleted. LLM call is stubbed deterministically."""
303
+ svc = _fresh_service(tmp_path)
304
+ a, b = _conflicted_pair(svc)
305
+
306
+ monkeypatch.setattr(
307
+ auto_resolver, "call_llm",
308
+ lambda prompt, _: '{"winner": "A", "reason": "stronger evidence"}',
309
+ )
310
+ result = resolve_conflict_pair(svc.store, a, b)
311
+
312
+ assert result["resolved"] is True
313
+ assert result["winner_id"] == a.id
314
+ assert result["loser_id"] == b.id
315
+
316
+ loser = svc.store.get_claim(b.id)
317
+ winner = svc.store.get_claim(a.id)
318
+ assert loser.status == "superseded" # preserved, not deleted
319
+ assert loser.replaced_by_claim_id == a.id
320
+ assert winner.status != "superseded"
321
+
322
+ def test_llm_picks_b_supersedes_a(self, tmp_path, monkeypatch):
323
+ """Contract: the survivor must follow the model's verdict, not argument
324
+ order. A 'B' vote supersedes claim A — the mirror of the 'A' case."""
325
+ svc = _fresh_service(tmp_path)
326
+ a, b = _conflicted_pair(svc)
327
+
328
+ monkeypatch.setattr(
329
+ auto_resolver, "call_llm",
330
+ lambda prompt, _: '{"winner": "B", "reason": "more specific"}',
331
+ )
332
+ result = resolve_conflict_pair(svc.store, a, b)
333
+
334
+ assert result["resolved"] is True
335
+ assert result["winner_id"] == b.id
336
+ assert result["loser_id"] == a.id
337
+ assert svc.store.get_claim(a.id).status == "superseded"
338
+ assert svc.store.get_claim(b.id).status != "superseded"
339
+
340
+ def test_llm_abstains_leaves_both_intact(self, tmp_path, monkeypatch):
341
+ """Contract: when the model returns no clear winner (verdict outside
342
+ {A,B}), NOTHING is superseded — both claims survive for human review.
343
+ Auto-resolution must never guess when the evaluator abstained."""
344
+ svc = _fresh_service(tmp_path)
345
+ a, b = _conflicted_pair(svc)
346
+
347
+ monkeypatch.setattr(
348
+ auto_resolver, "call_llm",
349
+ lambda prompt, _: '{"winner": "neither", "reason": "ambiguous"}',
350
+ )
351
+ result = resolve_conflict_pair(svc.store, a, b)
352
+
353
+ assert result["resolved"] is False
354
+ assert result["reason"] == "llm_undecided"
355
+ # Neither claim was touched.
356
+ assert svc.store.get_claim(a.id).status == "conflicted"
357
+ assert svc.store.get_claim(b.id).status == "conflicted"
358
+ assert svc.store.get_claim(a.id).replaced_by_claim_id is None
359
+ assert svc.store.get_claim(b.id).replaced_by_claim_id is None
360
+
361
+ def test_invalid_llm_json_is_treated_as_abstain(self, tmp_path, monkeypatch):
362
+ """Contract: a malformed LLM response degrades to abstain (resolved
363
+ False), not to a crash or an arbitrary supersession. Robustness against
364
+ a flaky model is part of the contract."""
365
+ svc = _fresh_service(tmp_path)
366
+ a, b = _conflicted_pair(svc)
367
+
368
+ monkeypatch.setattr(
369
+ auto_resolver, "call_llm",
370
+ lambda prompt, _: "this is not json at all",
371
+ )
372
+ result = resolve_conflict_pair(svc.store, a, b)
373
+
374
+ assert result["resolved"] is False
375
+ assert svc.store.get_claim(a.id).status == "conflicted"
376
+ assert svc.store.get_claim(b.id).status == "conflicted"
377
+
378
+ def test_auto_resolve_conflicts_groups_and_supersedes_one(self, tmp_path, monkeypatch):
379
+ """Contract: the batch entrypoint groups conflicted claims by
380
+ (subject, predicate, scope) and resolves within each group, reporting
381
+ an accurate resolved count. End-to-end LLM-driven supersession."""
382
+ svc = _fresh_service(tmp_path)
383
+ a, b = _conflicted_pair(svc)
384
+
385
+ monkeypatch.setattr(
386
+ auto_resolver, "call_llm",
387
+ lambda prompt, _: '{"winner": "A", "reason": "kept A"}',
388
+ )
389
+ counts = auto_resolve_conflicts(svc.store, limit=10)
390
+
391
+ assert counts["pairs_evaluated"] >= 1
392
+ assert counts["resolved"] >= 1
393
+ # Exactly one of the two ends up superseded.
394
+ statuses = {
395
+ svc.store.get_claim(a.id).status,
396
+ svc.store.get_claim(b.id).status,
397
+ }
398
+ assert "superseded" in statuses
399
+
400
+ def test_auto_resolve_no_conflicted_is_a_noop(self, tmp_path, monkeypatch):
401
+ """Contract: with no conflicted claims, the batch path returns zeroed
402
+ counts WITHOUT invoking the LLM — no wasted provider calls."""
403
+ svc = _fresh_service(tmp_path)
404
+ svc.ingest(
405
+ text="lonely fact", citations=[CitationInput(source="d1")],
406
+ subject="db", predicate="region", object_value="us-east",
407
+ )
408
+
409
+ def _boom(prompt, _): # pragma: no cover - must never run
410
+ raise AssertionError("LLM must not be called when nothing is conflicted")
411
+
412
+ monkeypatch.setattr(auto_resolver, "call_llm", _boom)
413
+ counts = auto_resolve_conflicts(svc.store, limit=10)
414
+
415
+ assert counts == {"pairs_evaluated": 0, "resolved": 0, "failed": 0}