memorymaster 3.25.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 (414) hide show
  1. {memorymaster-3.25.0/memorymaster.egg-info → memorymaster-3.26.1}/PKG-INFO +2 -2
  2. {memorymaster-3.25.0 → memorymaster-3.26.1}/README.md +1 -1
  3. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/__init__.py +1 -1
  4. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/contradiction_probe.py +70 -9
  5. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/query_cache.py +25 -1
  6. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/rule_miner.py +17 -0
  7. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/verbatim_cleanup.py +12 -3
  8. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/verbatim_store.py +80 -56
  9. {memorymaster-3.25.0 → memorymaster-3.26.1/memorymaster.egg-info}/PKG-INFO +2 -2
  10. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster.egg-info/SOURCES.txt +15 -0
  11. {memorymaster-3.25.0 → memorymaster-3.26.1}/pyproject.toml +1 -1
  12. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/bench_longmemeval.py +3 -2
  13. memorymaster-3.26.1/tests/test_bench_answer_prompt.py +75 -0
  14. memorymaster-3.26.1/tests/test_cli_handlers_extra.py +308 -0
  15. memorymaster-3.26.1/tests/test_conflict_resolver_extra.py +415 -0
  16. memorymaster-3.26.1/tests/test_context_hook_extra.py +643 -0
  17. memorymaster-3.26.1/tests/test_contradiction_probe.py +313 -0
  18. memorymaster-3.26.1/tests/test_db_merge_extra.py +237 -0
  19. memorymaster-3.26.1/tests/test_delta_sync_extra.py +392 -0
  20. memorymaster-3.26.1/tests/test_dream_bridge_extra.py +229 -0
  21. memorymaster-3.26.1/tests/test_entity_registry_extra.py +271 -0
  22. memorymaster-3.26.1/tests/test_lifecycle_extra.py +314 -0
  23. memorymaster-3.26.1/tests/test_llm_provider_extra.py +673 -0
  24. memorymaster-3.26.1/tests/test_observability_extra.py +335 -0
  25. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_query_cache.py +39 -0
  26. memorymaster-3.26.1/tests/test_retrieval_extra.py +320 -0
  27. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_rule_miner.py +51 -4
  28. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_service_coverage.py +96 -1
  29. memorymaster-3.26.1/tests/test_storage_extra.py +154 -0
  30. memorymaster-3.26.1/tests/test_vault_linter_extra.py +290 -0
  31. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_verbatim_cleanup.py +80 -0
  32. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_verbatim_dedup.py +48 -0
  33. memorymaster-3.26.1/tests/test_wiki_engine_extra.py +410 -0
  34. memorymaster-3.25.0/tests/test_contradiction_probe.py +0 -153
  35. {memorymaster-3.25.0 → memorymaster-3.26.1}/LICENSE +0 -0
  36. {memorymaster-3.25.0 → memorymaster-3.26.1}/artifacts/bm25-per-field-eval-harness.py +0 -0
  37. {memorymaster-3.25.0 → memorymaster-3.26.1}/benchmarks/longmemeval_runner.py +0 -0
  38. {memorymaster-3.25.0 → memorymaster-3.26.1}/benchmarks/longmemeval_vector_runner.py +0 -0
  39. {memorymaster-3.25.0 → memorymaster-3.26.1}/benchmarks/perf_smoke.py +0 -0
  40. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/__main__.py +0 -0
  41. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/_storage_lifecycle.py +0 -0
  42. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/_storage_read.py +0 -0
  43. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/_storage_schema.py +0 -0
  44. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/_storage_shared.py +0 -0
  45. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/_storage_sources.py +0 -0
  46. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/_storage_write_claims.py +0 -0
  47. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/access_control.py +0 -0
  48. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/action_exporters.py +0 -0
  49. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/action_extractor.py +0 -0
  50. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/atlas_claim_extractor.py +0 -0
  51. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/atlas_contract.py +0 -0
  52. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/auto_extractor.py +0 -0
  53. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/auto_resolver.py +0 -0
  54. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/candidate_dedupe.py +0 -0
  55. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/claim_edges.py +0 -0
  56. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/claim_verifier.py +0 -0
  57. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/cli.py +0 -0
  58. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/cli_handlers_basic.py +0 -0
  59. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/cli_handlers_curation.py +0 -0
  60. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/cli_helpers.py +0 -0
  61. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/closets.py +0 -0
  62. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config.py +0 -0
  63. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/claude-md-append.md +0 -0
  64. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/codex-agents-md-append.md +0 -0
  65. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-auto-ingest.py +0 -0
  66. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-classify.py +0 -0
  67. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-dream-sync.py +0 -0
  68. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-precompact.py +0 -0
  69. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-recall.py +0 -0
  70. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-session-start.py +0 -0
  71. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-steward-cycle.py +0 -0
  72. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/config_templates/hooks/memorymaster-validate-wiki.py +0 -0
  73. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/conflict_resolver.py +0 -0
  74. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/connectors/__init__.py +0 -0
  75. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/connectors/whatsapp.py +0 -0
  76. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/context_hook.py +0 -0
  77. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/context_optimizer.py +0 -0
  78. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/daily_notes.py +0 -0
  79. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/dashboard.py +0 -0
  80. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/dashboard_auth.py +0 -0
  81. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/db_merge.py +0 -0
  82. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/delta_sync.py +0 -0
  83. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/dream_bridge.py +0 -0
  84. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/embeddings.py +0 -0
  85. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/entity_extractor.py +0 -0
  86. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/entity_graph.py +0 -0
  87. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/entity_registry.py +0 -0
  88. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/federated_graphify.py +0 -0
  89. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/feedback.py +0 -0
  90. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/graph_store.py +0 -0
  91. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/hook_log.py +0 -0
  92. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/__init__.py +0 -0
  93. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/calibration.py +0 -0
  94. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/compact_summaries.py +0 -0
  95. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/compactor.py +0 -0
  96. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/daydream_ingest.py +0 -0
  97. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/decay.py +0 -0
  98. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/dedup.py +0 -0
  99. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/deterministic.py +0 -0
  100. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/entity_graph_export.py +0 -0
  101. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/extractor.py +0 -0
  102. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/staleness.py +0 -0
  103. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/jobs/validator.py +0 -0
  104. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/key_rotator.py +0 -0
  105. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/lifecycle.py +0 -0
  106. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/llm_budget.py +0 -0
  107. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/llm_provider.py +0 -0
  108. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/llm_rerank.py +0 -0
  109. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/llm_steward.py +0 -0
  110. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/mcp_path_policy.py +0 -0
  111. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/mcp_server.py +0 -0
  112. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/mcp_usage.py +0 -0
  113. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/media_processing.py +0 -0
  114. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/media_providers.py +0 -0
  115. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/metrics_exporter.py +0 -0
  116. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/migrations/0001_initial.py +0 -0
  117. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/migrations/0002_miner_state.py +0 -0
  118. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/migrations/0003_contradiction_verdicts.py +0 -0
  119. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/migrations/0004_query_cache.py +0 -0
  120. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/migrations/__init__.py +0 -0
  121. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/migrations/runner.py +0 -0
  122. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/models.py +0 -0
  123. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/observability.py +0 -0
  124. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/operator.py +0 -0
  125. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/operator_queue.py +0 -0
  126. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/plugins.py +0 -0
  127. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/policy.py +0 -0
  128. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/postgres_store.py +0 -0
  129. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/qdrant_backend.py +0 -0
  130. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/qdrant_recall_fallback.py +0 -0
  131. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/qmd_bridge.py +0 -0
  132. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/query_classifier.py +0 -0
  133. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/query_expansion.py +0 -0
  134. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/recall_fusion.py +0 -0
  135. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/recall_tokenizer.py +0 -0
  136. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/retrieval.py +0 -0
  137. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/retry.py +0 -0
  138. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/review.py +0 -0
  139. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/rl_trainer.py +0 -0
  140. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/rules.py +0 -0
  141. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/scheduler.py +0 -0
  142. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/schema.py +0 -0
  143. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/schema.sql +0 -0
  144. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/schema_postgres.sql +0 -0
  145. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/scope_utils.py +0 -0
  146. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/security.py +0 -0
  147. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/service.py +0 -0
  148. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/session_tracker.py +0 -0
  149. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/setup_hooks.py +0 -0
  150. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/skill_evolver.py +0 -0
  151. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/snapshot.py +0 -0
  152. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/steward.py +0 -0
  153. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/steward_classifier.py +0 -0
  154. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/steward_features.py +0 -0
  155. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/storage.py +0 -0
  156. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/store_factory.py +0 -0
  157. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/transcript_miner.py +0 -0
  158. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/turn_schema.py +0 -0
  159. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/vault_bases.py +0 -0
  160. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/vault_curator.py +0 -0
  161. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/vault_exporter.py +0 -0
  162. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/vault_linter.py +0 -0
  163. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/vault_log.py +0 -0
  164. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/vault_query_capture.py +0 -0
  165. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/vault_synthesis.py +0 -0
  166. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/verbatim_recall.py +0 -0
  167. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/webhook.py +0 -0
  168. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/wiki_engine.py +0 -0
  169. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/wiki_freshness.py +0 -0
  170. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/wiki_similarity.py +0 -0
  171. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/wiki_suggest.py +0 -0
  172. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster/wiki_validate.py +0 -0
  173. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster.egg-info/dependency_links.txt +0 -0
  174. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster.egg-info/entry_points.txt +0 -0
  175. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster.egg-info/requires.txt +0 -0
  176. {memorymaster-3.25.0 → memorymaster-3.26.1}/memorymaster.egg-info/top_level.txt +0 -0
  177. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/agg_recall_latency.py +0 -0
  178. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/alert_operator_metrics.py +0 -0
  179. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/audit_dedupe_precision.py +0 -0
  180. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/autoresearch_daemon.py +0 -0
  181. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/backfill_entity_extraction.py +0 -0
  182. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/backfill_graph_store.py +0 -0
  183. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/backfill_stop_hook_citations.py +0 -0
  184. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/backtest_steward_classifier.py +0 -0
  185. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/build_steward_training_set.py +0 -0
  186. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/check_hook_template_drift.py +0 -0
  187. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/claude_to_turns.py +0 -0
  188. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/codex_live_to_turns.py +0 -0
  189. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/compaction_edge_cases.py +0 -0
  190. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/compaction_trace_report.py +0 -0
  191. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/compaction_trace_validate.py +0 -0
  192. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/confusion_matrix_eval.py +0 -0
  193. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/conversation_importer.py +0 -0
  194. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/conversation_to_turns.py +0 -0
  195. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/e2e_operator.py +0 -0
  196. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/email_live_to_turns.py +0 -0
  197. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/eval_bm25_sweep.py +0 -0
  198. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/eval_classify_f1.py +0 -0
  199. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/eval_memorymaster.py +0 -0
  200. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/eval_recall_precision_at_5.py +0 -0
  201. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/eval_recall_quality.py +0 -0
  202. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/eval_steward_pareto.py +0 -0
  203. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/eval_verbatim_recall.py +0 -0
  204. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/expand_recall_eval.py +0 -0
  205. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/generate_drill_signoff.py +0 -0
  206. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/git_to_turns.py +0 -0
  207. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/github_live_to_turns.py +0 -0
  208. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/gitnexus_to_claims.py +0 -0
  209. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/grid_recall_weights.py +0 -0
  210. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/index_claims_to_qdrant.py +0 -0
  211. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/ingest_planning_docs.py +0 -0
  212. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/jira_live_to_turns.py +0 -0
  213. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/label_prompts_with_judge.py +0 -0
  214. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/llm_benchmark.py +0 -0
  215. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/measure_dedupe_thresholds.py +0 -0
  216. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/merge_scope_variants.py +0 -0
  217. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/messages_to_turns.py +0 -0
  218. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/operator_metrics.py +0 -0
  219. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/precompute_candidates.py +0 -0
  220. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/recurring_incident_drill.py +0 -0
  221. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/release_readiness.py +0 -0
  222. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/run_codex_autologger.py +0 -0
  223. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/run_incident_drill.py +0 -0
  224. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/scheduled_ingest.py +0 -0
  225. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/setup-hooks.py +0 -0
  226. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/slack_live_to_turns.py +0 -0
  227. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/sync_hook_templates.py +0 -0
  228. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/tickets_to_turns.py +0 -0
  229. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/train_steward_classifier.py +0 -0
  230. {memorymaster-3.25.0 → memorymaster-3.26.1}/scripts/webhook_to_turns.py +0 -0
  231. {memorymaster-3.25.0 → memorymaster-3.26.1}/setup.cfg +0 -0
  232. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/conftest.py +0 -0
  233. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/integration/test_extract_llm_ollama_live.py +0 -0
  234. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_access_control.py +0 -0
  235. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_action_exporters.py +0 -0
  236. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_action_extractor.py +0 -0
  237. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_atlas_claim_extractor.py +0 -0
  238. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_atlas_contract.py +0 -0
  239. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_atlas_source_schema.py +0 -0
  240. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_auto_extractor.py +0 -0
  241. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_auto_ingest_hook_citations.py +0 -0
  242. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_auto_ingest_hook_schema.py +0 -0
  243. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_auto_resolver.py +0 -0
  244. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_auto_validate.py +0 -0
  245. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_backend_parity.py +0 -0
  246. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_bm25_per_field.py +0 -0
  247. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_calibration.py +0 -0
  248. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_calibration_priors_applied.py +0 -0
  249. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_candidate_dedupe.py +0 -0
  250. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_claim_edges.py +0 -0
  251. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_claim_links.py +0 -0
  252. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_claim_type_ranking.py +0 -0
  253. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_classify_hook_f1.py +0 -0
  254. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_classify_hook_latency.py +0 -0
  255. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_claude_to_turns.py +0 -0
  256. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_cli_dry_run.py +0 -0
  257. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_cli_json_flag.py +0 -0
  258. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_cli_ready.py +0 -0
  259. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_cli_review_queue.py +0 -0
  260. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_cli_subcommands.py +0 -0
  261. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_closets.py +0 -0
  262. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_closets_recall_integration.py +0 -0
  263. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_compact_summaries.py +0 -0
  264. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_compact_summaries_sensitivity.py +0 -0
  265. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_compaction_trace.py +0 -0
  266. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_compactor_artifact_order.py +0 -0
  267. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_config.py +0 -0
  268. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_conflict_resolver.py +0 -0
  269. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_confusion_matrix_eval.py +0 -0
  270. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_connection_retry.py +0 -0
  271. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_connectors.py +0 -0
  272. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_context_hook.py +0 -0
  273. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_context_optimizer.py +0 -0
  274. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_context_optimizer_provider.py +0 -0
  275. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_conversation_to_turns.py +0 -0
  276. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dashboard.py +0 -0
  277. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dashboard_auth.py +0 -0
  278. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dashboard_coverage.py +0 -0
  279. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dashboard_latency.py +0 -0
  280. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dashboard_lineage.py +0 -0
  281. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dashboard_review_queue.py +0 -0
  282. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_daydream_ingest.py +0 -0
  283. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_db_merge_confidence_conflict.py +0 -0
  284. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_db_merge_coverage_v2.py +0 -0
  285. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_decay_coverage.py +0 -0
  286. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_decay_respects_pinned.py +0 -0
  287. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dedup.py +0 -0
  288. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dedup_cli.py +0 -0
  289. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dedup_conflict_disambiguation.py +0 -0
  290. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_delta_sync.py +0 -0
  291. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_deterministic_predicates.py +0 -0
  292. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dream_bridge_coverage_v2.py +0 -0
  293. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_dream_bridge_sensitivity.py +0 -0
  294. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_embeddings_coverage.py +0 -0
  295. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_entity_extractor.py +0 -0
  296. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_entity_extractor_llm.py +0 -0
  297. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_entity_graph.py +0 -0
  298. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_entity_graph_export.py +0 -0
  299. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_entity_new_kinds.py +0 -0
  300. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_entity_regex_v3.py +0 -0
  301. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_entity_registry.py +0 -0
  302. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_eval_harness.py +0 -0
  303. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_events_schema.py +0 -0
  304. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_extract_llm_ollama.py +0 -0
  305. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_federated_graphify_mcp.py +0 -0
  306. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_federated_query_safety.py +0 -0
  307. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_feedback.py +0 -0
  308. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_floor_gate.py +0 -0
  309. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_fts5_search.py +0 -0
  310. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_graph_distance.py +0 -0
  311. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_graph_store.py +0 -0
  312. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_handler_regressions.py +0 -0
  313. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_hook_env_isolation.py +0 -0
  314. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_human_id.py +0 -0
  315. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_incident_drill_runner.py +0 -0
  316. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_integration_workflows.py +0 -0
  317. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_key_rotator.py +0 -0
  318. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_lifecycle.py +0 -0
  319. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_lifecycle_supersede_invariant.py +0 -0
  320. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_llm_budget.py +0 -0
  321. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_llm_fallback.py +0 -0
  322. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_llm_provider_claude_cli.py +0 -0
  323. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_llm_provider_key_rotation.py +0 -0
  324. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_llm_steward_coverage.py +0 -0
  325. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_llm_steward_key_rotation.py +0 -0
  326. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_mcp_filter_bypass.py +0 -0
  327. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_mcp_helpers.py +0 -0
  328. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_mcp_path_policy.py +0 -0
  329. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_mcp_rate_limit.py +0 -0
  330. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_mcp_server_validation.py +0 -0
  331. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_mcp_usage.py +0 -0
  332. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_media_processing.py +0 -0
  333. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_meta_decisions.py +0 -0
  334. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_metrics_exporter.py +0 -0
  335. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_migrations.py +0 -0
  336. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_observability.py +0 -0
  337. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_obsidian_mind_patterns.py +0 -0
  338. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_operator.py +0 -0
  339. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_operator_queue.py +0 -0
  340. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_perf_smoke_config.py +0 -0
  341. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_plugins.py +0 -0
  342. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_policy_coverage.py +0 -0
  343. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_policy_mode_env.py +0 -0
  344. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_postgres_parity.py +0 -0
  345. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_qdrant_backend.py +0 -0
  346. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_qmd_bridge.py +0 -0
  347. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_qrels_regression.py +0 -0
  348. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_query_classifier.py +0 -0
  349. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_query_expansion.py +0 -0
  350. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_recall_entity_fanout.py +0 -0
  351. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_recall_fusion.py +0 -0
  352. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_recall_latency.py +0 -0
  353. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_recall_precision_at_5.py +0 -0
  354. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_recall_tokenizer.py +0 -0
  355. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_recall_vector_fallback.py +0 -0
  356. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_reliability_hardening.py +0 -0
  357. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_resolvers_concurrent_supersede.py +0 -0
  358. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_retrieval_profile.py +0 -0
  359. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_retrieval_profiles.py +0 -0
  360. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_retrieval_rrf_tiebreaker.py +0 -0
  361. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_retrieval_weights.py +0 -0
  362. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_review.py +0 -0
  363. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_rl_trainer.py +0 -0
  364. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_rrf_auto_gate.py +0 -0
  365. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_rule_claims.py +0 -0
  366. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_scheduler.py +0 -0
  367. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_schema.py +0 -0
  368. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_scope_boost.py +0 -0
  369. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_scope_utils.py +0 -0
  370. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_security_access.py +0 -0
  371. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_security_patterns.py +0 -0
  372. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_sensitivity_filter_adversarial.py +0 -0
  373. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_sensitivity_filter_adversarial_v2.py +0 -0
  374. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_sensitivity_filter_t07.py +0 -0
  375. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_session_tracker.py +0 -0
  376. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_snapshot.py +0 -0
  377. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_snapshot_roundtrip.py +0 -0
  378. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_sqlite_core.py +0 -0
  379. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_staleness.py +0 -0
  380. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_stealth_mode.py +0 -0
  381. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_steward.py +0 -0
  382. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_steward_classifier.py +0 -0
  383. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_steward_contradiction_phase.py +0 -0
  384. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_steward_daydream_hook.py +0 -0
  385. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_steward_features.py +0 -0
  386. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_steward_features_v3.py +0 -0
  387. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_steward_resolution_parity.py +0 -0
  388. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_storage_parity.py +0 -0
  389. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_store_factory.py +0 -0
  390. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_tenant_isolation.py +0 -0
  391. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_turn_schema.py +0 -0
  392. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_two_pass_recall.py +0 -0
  393. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_v311_fixes.py +0 -0
  394. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_v313_e2e.py +0 -0
  395. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_v313_run_cycle_dedupe.py +0 -0
  396. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_v390_e2e.py +0 -0
  397. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_v391_strict_warnings.py +0 -0
  398. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_vault_exporter.py +0 -0
  399. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_vault_linter_orphan.py +0 -0
  400. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_vector_search.py +0 -0
  401. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_verbatim_recall.py +0 -0
  402. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_verbatim_store.py +0 -0
  403. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_verbatim_store_qdrant.py +0 -0
  404. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_webhook.py +0 -0
  405. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_webhook_hmac.py +0 -0
  406. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_whatsapp_importer.py +0 -0
  407. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_wiki_autopromote.py +0 -0
  408. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_wiki_binding.py +0 -0
  409. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_wiki_engine_idempotency.py +0 -0
  410. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_wiki_explored_and_contradictions.py +0 -0
  411. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_wiki_freshness.py +0 -0
  412. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_wiki_similarity_multiscope.py +0 -0
  413. {memorymaster-3.25.0 → memorymaster-3.26.1}/tests/test_wiki_suggest.py +0 -0
  414. {memorymaster-3.25.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.25.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-2232-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-2232-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.25.0"
5
+ __version__ = "3.26.1"
@@ -77,9 +77,23 @@ def _canonical_pair(a_id: int, b_id: int) -> tuple[int, int]:
77
77
  return (a_id, b_id) if a_id <= b_id else (b_id, a_id)
78
78
 
79
79
 
80
- def _ensure_verdict_table(conn: sqlite3.Connection) -> None:
80
+ _ensured_verdict_dbs: set[str] = set()
81
+
82
+
83
+ def _ensure_verdict_table(conn: sqlite3.Connection, *, db_key: str | None = None) -> None:
84
+ """Create the verdict cache table if absent.
85
+
86
+ ``db_key`` lets per-claim callers skip the redundant ``CREATE TABLE IF NOT
87
+ EXISTS`` + ``commit`` on every claim in a steward cycle: once a given DB has
88
+ been ensured in this process we never re-issue the DDL. ``run_probe`` (one
89
+ DDL per whole run) passes no key and always ensures, preserving its semantics.
90
+ """
91
+ if db_key is not None and db_key in _ensured_verdict_dbs:
92
+ return
81
93
  conn.execute(_VERDICT_DDL)
82
94
  conn.commit()
95
+ if db_key is not None:
96
+ _ensured_verdict_dbs.add(db_key)
83
97
 
84
98
 
85
99
  def _cache_get(conn: sqlite3.Connection, a_id: int, b_id: int, model: str) -> dict | None:
@@ -164,13 +178,23 @@ def sample_candidate_pairs(
164
178
  return []
165
179
  embeddings = [provider.embed(_embed_text(c)) for c in usable]
166
180
  pairs: list[tuple[Claim, Claim, float]] = []
181
+ # The cosine sweep is O(n^2). Once we have already collected ``limit`` in-band
182
+ # pairs there is no point paying for the rest of the quadratic scan — the
183
+ # caller only ever consumes the first ``limit`` after the sort below, so break
184
+ # early instead of building (then discarding) thousands of extra pairs.
185
+ done = False
167
186
  for i in range(len(usable)):
187
+ if done:
188
+ break
168
189
  for j in range(i + 1, len(usable)):
169
190
  if _prefiltered(usable[i], usable[j]):
170
191
  continue
171
192
  sim = cosine_similarity(embeddings[i], embeddings[j])
172
193
  if sim_low <= sim < sim_high:
173
194
  pairs.append((usable[i], usable[j], round(sim, 4)))
195
+ if limit is not None and len(pairs) >= limit:
196
+ done = True
197
+ break
174
198
  pairs.sort(key=lambda p: -p[2])
175
199
  if limit is not None:
176
200
  pairs = pairs[:limit]
@@ -193,7 +217,11 @@ def _judge_llm(a: Claim, b: Claim) -> dict | None:
193
217
  if isinstance(item, dict) and "contradicts" in item:
194
218
  return {
195
219
  "contradicts": bool(item.get("contradicts")),
196
- "severity": (item.get("severity") or "low").strip().lower(),
220
+ # Floor empty/off-vocabulary severity to "medium" at the source
221
+ # (the JSON contract is advisory). Defaulting to "low" here would
222
+ # silently bury a real contradiction in the least-actionable tier
223
+ # and made the "medium" default downstream dead code.
224
+ "severity": _coerce_severity(item.get("severity")),
197
225
  "reason": (item.get("reason") or "").strip(),
198
226
  "cached": False,
199
227
  }
@@ -206,6 +234,36 @@ def _model_key() -> str:
206
234
  return f"{provider}:{model}"
207
235
 
208
236
 
237
+ _VALID_SEVERITIES = {"low", "medium", "high"}
238
+
239
+
240
+ def _coerce_severity(value: Any) -> str:
241
+ """Normalize a verdict severity to a canonical bucket.
242
+
243
+ The LLM judge and verdict cache can both yield an empty or off-vocabulary
244
+ severity (the JSON contract is advisory, not enforced). When that happens we
245
+ floor to ``"medium"`` rather than ``"low"`` so a contradiction surfaced by
246
+ the probe is never silently downgraded to the least-actionable tier.
247
+ """
248
+ sev = str(value or "").strip().lower()
249
+ return sev if sev in _VALID_SEVERITIES else "medium"
250
+
251
+
252
+ def _safe_judge_reason(reason: Any) -> str | None:
253
+ """Return the raw judge reason unless it leaks sensitive content.
254
+
255
+ Both ``probe_for_claim`` and ``run_probe(apply=True)`` persist/surface the
256
+ LLM judge reason. Routing both through this guard ensures a reason that the
257
+ sensitivity filter flags is dropped (returns ``None``) on EVERY path — the
258
+ events table must never receive an unredacted secret.
259
+ """
260
+ text = str(reason or "")
261
+ _, leaks = redact_text(text)
262
+ if leaks:
263
+ return None
264
+ return text
265
+
266
+
209
267
  # ---------------------------------------------------------------------------
210
268
  # Wilson confidence interval
211
269
  # ---------------------------------------------------------------------------
@@ -303,15 +361,19 @@ def run_probe(
303
361
  if verdict["contradicts"]:
304
362
  stats["contradictions"] += 1
305
363
  loser, winner = (a, b) if a.confidence <= b.confidence else (b, a)
364
+ # Same sensitivity guard the per-claim path uses: never let an
365
+ # unredacted judge reason reach the events table on apply.
366
+ safe_reason = _safe_judge_reason(verdict.get("reason"))
306
367
  stats["found"].append({
307
368
  "claim_a_id": a.id, "claim_b_id": b.id, "similarity": sim,
308
- "severity": verdict["severity"], "reason": verdict["reason"],
369
+ "severity": verdict["severity"], "reason": verdict.get("reason", ""),
309
370
  "flag_candidate_id": loser.id,
310
371
  })
311
372
  if apply:
373
+ detail = f" ({safe_reason})" if safe_reason else ""
312
374
  transition_claim(
313
375
  service.store, loser.id, "conflicted",
314
- reason=f"contradiction_probe: contradicts claim {winner.id} ({verdict['reason']})",
376
+ reason=f"contradiction_probe: contradicts claim {winner.id}{detail}",
315
377
  event_type="transition",
316
378
  )
317
379
  stats["flagged_conflicted"] += 1
@@ -415,7 +477,7 @@ def probe_for_claim(
415
477
 
416
478
  conn = sqlite3.connect(str(db_path))
417
479
  try:
418
- _ensure_verdict_table(conn)
480
+ _ensure_verdict_table(conn, db_key=str(db_path))
419
481
  model = _model_key()
420
482
  for peer, sim in candidates:
421
483
  metrics["pairs_checked"] += 1
@@ -439,14 +501,13 @@ def probe_for_claim(
439
501
  _cache_put(conn, claim.id, peer.id, model, verdict)
440
502
  if not verdict.get("contradicts"):
441
503
  continue
442
- verdict_reason = verdict.get("reason", "")
443
- _, leaks = redact_text(verdict_reason)
444
- if leaks:
504
+ verdict_reason = _safe_judge_reason(verdict.get("reason"))
505
+ if verdict_reason is None:
445
506
  continue # drop rather than surface a sensitive judge-reason
446
507
  metrics["contradictions"] += 1
447
508
  reasons.append({
448
509
  "code": "contradiction_probe.semantic_pair",
449
- "severity": verdict.get("severity", "medium"),
510
+ "severity": _coerce_severity(verdict.get("severity")),
450
511
  "detail": f"Semantic contradiction with claim {peer.id}: {verdict_reason}",
451
512
  "evidence": {
452
513
  "peer_claim_id": int(peer.id),
@@ -116,7 +116,14 @@ def read(db_path: str, cache_key: str) -> list[dict] | None:
116
116
  "SELECT result_json, generation FROM query_cache WHERE cache_key = ?",
117
117
  (cache_key,),
118
118
  ).fetchone()
119
- if row is None or int(row["generation"]) != gen:
119
+ if row is None:
120
+ return None
121
+ if int(row["generation"]) != gen:
122
+ try:
123
+ conn.execute("DELETE FROM query_cache WHERE cache_key = ?", (cache_key,))
124
+ conn.commit()
125
+ except sqlite3.Error:
126
+ pass
120
127
  return None
121
128
  return json.loads(row["result_json"])
122
129
  except (sqlite3.Error, json.JSONDecodeError, ValueError) as exc:
@@ -126,6 +133,23 @@ def read(db_path: str, cache_key: str) -> list[dict] | None:
126
133
  conn.close()
127
134
 
128
135
 
136
+ def evict_stale(db_path: str) -> None:
137
+ """Delete query cache rows older than the current corpus generation."""
138
+ try:
139
+ conn = _connect(db_path)
140
+ except sqlite3.Error as exc:
141
+ logger.warning("query_cache.evict_stale connect failed: %s", exc)
142
+ return
143
+ try:
144
+ gen = current_generation(conn)
145
+ conn.execute("DELETE FROM query_cache WHERE generation < ?", (gen,))
146
+ conn.commit()
147
+ except (sqlite3.Error, ValueError) as exc:
148
+ logger.warning("query_cache.evict_stale failed: %s", exc)
149
+ finally:
150
+ conn.close()
151
+
152
+
129
153
  def write(db_path: str, cache_key: str, stub_rows: list[dict], generation: int) -> None:
130
154
  """Store result stubs tagged with ``generation``. Best-effort.
131
155
 
@@ -48,6 +48,11 @@ _CORRECTION_KEYWORDS = (
48
48
  "wrong", "not what", "that's not", "thats not", "revert", "undo",
49
49
  "should have", "shouldn't", "why did you", "no need", "stop ",
50
50
  )
51
+ _CORRECTION_FTS_MATCH = (
52
+ '"no" OR "don" OR "do" OR "dont" OR "instead" OR "actually" OR '
53
+ '"wrong" OR "not" OR "revert" OR "undo" OR "should" OR "shouldn" OR '
54
+ '"why" OR "stop"'
55
+ )
51
56
 
52
57
  _MINER_STATE_DDL = """
53
58
  CREATE TABLE IF NOT EXISTS miner_state (
@@ -132,6 +137,18 @@ def _candidate_batch(
132
137
  params: list[Any] = [since_id]
133
138
  params.extend(f"%{kw}%" for kw in _CORRECTION_KEYWORDS)
134
139
  params.append(batch_size)
140
+ try:
141
+ return conn.execute(
142
+ f"""SELECT v.id, v.session_id, v.content, v.scope FROM verbatim_fts f
143
+ JOIN verbatim_memories v ON v.id = f.rowid
144
+ WHERE verbatim_fts MATCH ?
145
+ AND v.role = 'user' AND v.id > ? AND ({like_clause})
146
+ ORDER BY v.id ASC LIMIT ?""",
147
+ [_CORRECTION_FTS_MATCH, *params],
148
+ ).fetchall()
149
+ except sqlite3.Error as exc:
150
+ logger.debug("rule_miner: verbatim_fts pre-filter failed, using LIKE scan: %s", exc)
151
+
135
152
  return conn.execute(
136
153
  f"""SELECT id, session_id, content, scope FROM verbatim_memories
137
154
  WHERE role = 'user' AND id > ? AND ({like_clause})
@@ -132,10 +132,19 @@ def cleanup(
132
132
 
133
133
  if dedup:
134
134
  # Identify ids to drop: for each (session_id, content) group, keep
135
- # the smallest id (oldest), drop the rest.
135
+ # the smallest id (oldest), drop the rest. NOT EXISTS against a
136
+ # correlated "is there an older twin?" probe avoids the O(n^2)
137
+ # full-table anti-join that `id NOT IN (SELECT MIN(id) ...)` forces
138
+ # SQLite into on the cold CLI path. Results are identical: a row is
139
+ # dropped iff another row in the same (session_id, content) group has
140
+ # a strictly smaller id.
136
141
  rows = conn.execute(
137
- """SELECT id FROM verbatim_memories WHERE id NOT IN (
138
- SELECT MIN(id) FROM verbatim_memories GROUP BY session_id, content
142
+ """SELECT id FROM verbatim_memories AS v
143
+ WHERE EXISTS (
144
+ SELECT 1 FROM verbatim_memories AS older
145
+ WHERE older.session_id IS v.session_id
146
+ AND older.content = v.content
147
+ AND older.id < v.id
139
148
  )"""
140
149
  ).fetchall()
141
150
  ids = [int(r[0]) for r in rows]
@@ -22,11 +22,11 @@ from datetime import datetime, timezone
22
22
  from pathlib import Path
23
23
  from typing import Any
24
24
 
25
+ # Credential detection delegated to the canonical filter in memorymaster.security.
26
+ from memorymaster.security import redact_text as _redact_text
27
+
25
28
  logger = logging.getLogger(__name__)
26
29
 
27
- # Credential detection delegated to the canonical filter in
28
- # memorymaster.security — single source of truth.
29
- from memorymaster.security import redact_text as _redact_text
30
30
 
31
31
 
32
32
  def _contains_sensitive(text: str) -> bool:
@@ -76,6 +76,33 @@ def store_verbatim(
76
76
  timestamp: str | None = None,
77
77
  ) -> int | None:
78
78
  """Store a verbatim conversation turn. Returns row ID or None if filtered."""
79
+ # closing() guarantees the connection (and its WAL write lock) is released
80
+ # even if an INSERT/commit raises (e.g. "database is locked" under
81
+ # concurrent MCP/Stop-hook writers) - this is the hottest write path.
82
+ with closing(_connect(db_path)) as conn:
83
+ row_id = _store_verbatim_conn(
84
+ conn,
85
+ session_id,
86
+ role,
87
+ content,
88
+ scope,
89
+ source_agent,
90
+ timestamp,
91
+ )
92
+ conn.commit()
93
+ return row_id
94
+
95
+
96
+ def _store_verbatim_conn(
97
+ conn: sqlite3.Connection,
98
+ session_id: str,
99
+ role: str,
100
+ content: str,
101
+ scope: str = "project",
102
+ source_agent: str = "",
103
+ timestamp: str | None = None,
104
+ ) -> int | None:
105
+ """Store one turn using an existing connection without committing."""
79
106
  if not content or len(content) < 20:
80
107
  return None
81
108
  if _row_has_sensitive_field(role or "", source_agent or "", content):
@@ -83,37 +110,32 @@ def store_verbatim(
83
110
 
84
111
  now = timestamp or datetime.now(timezone.utc).isoformat()
85
112
 
86
- # closing() guarantees the connection (and its WAL write lock) is released
87
- # even if an INSERT/commit raises (e.g. "database is locked" under
88
- # concurrent MCP/Stop-hook writers) this is the hottest write path.
89
- with closing(_connect(db_path)) as conn:
90
- # Dedup by exact content within the same session. Uses idx_verbatim_session
91
- # so the lookup is O(rows-in-session), not table-scan. The previous FTS5-based
92
- # dedup query passed a sha256 hex prefix to MATCH which never resolves —
93
- # the FTS5 index stores the content text, not its hash. Result: 9M+ rows
94
- # accumulated for orchestrator sessions because every Stop event re-inserted
95
- # every message. Fixed 2026-05-03; see mm-0c43.
96
- existing = conn.execute(
97
- "SELECT id FROM verbatim_memories WHERE session_id = ? AND content = ? LIMIT 1",
98
- (session_id, content),
99
- ).fetchone()
100
- if existing:
101
- return None
102
-
103
- cur = conn.execute(
104
- """INSERT INTO verbatim_memories (session_id, role, content, scope, timestamp, source_agent)
105
- VALUES (?, ?, ?, ?, ?, ?)""",
106
- (session_id, role, content, scope, now, source_agent),
107
- )
108
- row_id = cur.lastrowid
113
+ # Dedup by exact content within the same session. Uses idx_verbatim_session
114
+ # so the lookup is O(rows-in-session), not table-scan. The previous FTS5-based
115
+ # dedup query passed a sha256 hex prefix to MATCH which never resolves -
116
+ # the FTS5 index stores the content text, not its hash. Result: 9M+ rows
117
+ # accumulated for orchestrator sessions because every Stop event re-inserted
118
+ # every message. Fixed 2026-05-03; see mm-0c43.
119
+ existing = conn.execute(
120
+ "SELECT id FROM verbatim_memories WHERE session_id = ? AND content = ? LIMIT 1",
121
+ (session_id, content),
122
+ ).fetchone()
123
+ if existing:
124
+ return None
109
125
 
110
- # Update FTS
111
- conn.execute(
112
- "INSERT INTO verbatim_fts(rowid, content) VALUES (?, ?)",
113
- (row_id, content),
114
- )
115
- conn.commit()
116
- return row_id
126
+ cur = conn.execute(
127
+ """INSERT INTO verbatim_memories (session_id, role, content, scope, timestamp, source_agent)
128
+ VALUES (?, ?, ?, ?, ?, ?)""",
129
+ (session_id, role, content, scope, now, source_agent),
130
+ )
131
+ row_id = cur.lastrowid
132
+
133
+ # Update FTS
134
+ conn.execute(
135
+ "INSERT INTO verbatim_fts(rowid, content) VALUES (?, ?)",
136
+ (row_id, content),
137
+ )
138
+ return row_id
117
139
 
118
140
 
119
141
  def _extract_role_content(entry: dict) -> tuple[str, str]:
@@ -164,29 +186,31 @@ def store_transcript(
164
186
  stats = {"stored": 0, "skipped": 0}
165
187
  session_id = path.stem # Use filename as session ID
166
188
 
167
- for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
168
- if not line.strip():
169
- continue
170
- try:
171
- entry = json.loads(line)
172
- except json.JSONDecodeError:
173
- continue
174
- if not isinstance(entry, dict):
175
- continue
176
-
177
- role, content = _extract_role_content(entry)
178
- if role not in ("user", "assistant"):
179
- stats["skipped"] += 1
180
- continue
181
- if not content or len(content) < 20:
182
- stats["skipped"] += 1
183
- continue
184
-
185
- row_id = store_verbatim(db_path, session_id, role, content, scope, source_agent)
186
- if row_id:
187
- stats["stored"] += 1
188
- else:
189
- stats["skipped"] += 1
189
+ with closing(_connect(db_path)) as conn:
190
+ for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
191
+ if not line.strip():
192
+ continue
193
+ try:
194
+ entry = json.loads(line)
195
+ except json.JSONDecodeError:
196
+ continue
197
+ if not isinstance(entry, dict):
198
+ continue
199
+
200
+ role, content = _extract_role_content(entry)
201
+ if role not in ("user", "assistant"):
202
+ stats["skipped"] += 1
203
+ continue
204
+ if not content or len(content) < 20:
205
+ stats["skipped"] += 1
206
+ continue
207
+
208
+ row_id = _store_verbatim_conn(conn, session_id, role, content, scope, source_agent)
209
+ if row_id:
210
+ stats["stored"] += 1
211
+ else:
212
+ stats["skipped"] += 1
213
+ conn.commit()
190
214
 
191
215
  return stats
192
216
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memorymaster
3
- Version: 3.25.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-2232-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/)
@@ -218,6 +218,7 @@ tests/test_auto_ingest_hook_schema.py
218
218
  tests/test_auto_resolver.py
219
219
  tests/test_auto_validate.py
220
220
  tests/test_backend_parity.py
221
+ tests/test_bench_answer_prompt.py
221
222
  tests/test_bm25_per_field.py
222
223
  tests/test_calibration.py
223
224
  tests/test_calibration_priors_applied.py
@@ -229,6 +230,7 @@ tests/test_classify_hook_f1.py
229
230
  tests/test_classify_hook_latency.py
230
231
  tests/test_claude_to_turns.py
231
232
  tests/test_cli_dry_run.py
233
+ tests/test_cli_handlers_extra.py
232
234
  tests/test_cli_json_flag.py
233
235
  tests/test_cli_ready.py
234
236
  tests/test_cli_review_queue.py
@@ -241,10 +243,12 @@ tests/test_compaction_trace.py
241
243
  tests/test_compactor_artifact_order.py
242
244
  tests/test_config.py
243
245
  tests/test_conflict_resolver.py
246
+ tests/test_conflict_resolver_extra.py
244
247
  tests/test_confusion_matrix_eval.py
245
248
  tests/test_connection_retry.py
246
249
  tests/test_connectors.py
247
250
  tests/test_context_hook.py
251
+ tests/test_context_hook_extra.py
248
252
  tests/test_context_optimizer.py
249
253
  tests/test_context_optimizer_provider.py
250
254
  tests/test_contradiction_probe.py
@@ -258,14 +262,17 @@ tests/test_dashboard_review_queue.py
258
262
  tests/test_daydream_ingest.py
259
263
  tests/test_db_merge_confidence_conflict.py
260
264
  tests/test_db_merge_coverage_v2.py
265
+ tests/test_db_merge_extra.py
261
266
  tests/test_decay_coverage.py
262
267
  tests/test_decay_respects_pinned.py
263
268
  tests/test_dedup.py
264
269
  tests/test_dedup_cli.py
265
270
  tests/test_dedup_conflict_disambiguation.py
266
271
  tests/test_delta_sync.py
272
+ tests/test_delta_sync_extra.py
267
273
  tests/test_deterministic_predicates.py
268
274
  tests/test_dream_bridge_coverage_v2.py
275
+ tests/test_dream_bridge_extra.py
269
276
  tests/test_dream_bridge_sensitivity.py
270
277
  tests/test_embeddings_coverage.py
271
278
  tests/test_entity_extractor.py
@@ -275,6 +282,7 @@ tests/test_entity_graph_export.py
275
282
  tests/test_entity_new_kinds.py
276
283
  tests/test_entity_regex_v3.py
277
284
  tests/test_entity_registry.py
285
+ tests/test_entity_registry_extra.py
278
286
  tests/test_eval_harness.py
279
287
  tests/test_events_schema.py
280
288
  tests/test_extract_llm_ollama.py
@@ -292,10 +300,12 @@ tests/test_incident_drill_runner.py
292
300
  tests/test_integration_workflows.py
293
301
  tests/test_key_rotator.py
294
302
  tests/test_lifecycle.py
303
+ tests/test_lifecycle_extra.py
295
304
  tests/test_lifecycle_supersede_invariant.py
296
305
  tests/test_llm_budget.py
297
306
  tests/test_llm_fallback.py
298
307
  tests/test_llm_provider_claude_cli.py
308
+ tests/test_llm_provider_extra.py
299
309
  tests/test_llm_provider_key_rotation.py
300
310
  tests/test_llm_steward_coverage.py
301
311
  tests/test_llm_steward_key_rotation.py
@@ -310,6 +320,7 @@ tests/test_meta_decisions.py
310
320
  tests/test_metrics_exporter.py
311
321
  tests/test_migrations.py
312
322
  tests/test_observability.py
323
+ tests/test_observability_extra.py
313
324
  tests/test_obsidian_mind_patterns.py
314
325
  tests/test_operator.py
315
326
  tests/test_operator_queue.py
@@ -332,6 +343,7 @@ tests/test_recall_tokenizer.py
332
343
  tests/test_recall_vector_fallback.py
333
344
  tests/test_reliability_hardening.py
334
345
  tests/test_resolvers_concurrent_supersede.py
346
+ tests/test_retrieval_extra.py
335
347
  tests/test_retrieval_profile.py
336
348
  tests/test_retrieval_profiles.py
337
349
  tests/test_retrieval_rrf_tiebreaker.py
@@ -364,6 +376,7 @@ tests/test_steward_daydream_hook.py
364
376
  tests/test_steward_features.py
365
377
  tests/test_steward_features_v3.py
366
378
  tests/test_steward_resolution_parity.py
379
+ tests/test_storage_extra.py
367
380
  tests/test_storage_parity.py
368
381
  tests/test_store_factory.py
369
382
  tests/test_tenant_isolation.py
@@ -375,6 +388,7 @@ tests/test_v313_run_cycle_dedupe.py
375
388
  tests/test_v390_e2e.py
376
389
  tests/test_v391_strict_warnings.py
377
390
  tests/test_vault_exporter.py
391
+ tests/test_vault_linter_extra.py
378
392
  tests/test_vault_linter_orphan.py
379
393
  tests/test_vector_search.py
380
394
  tests/test_verbatim_cleanup.py
@@ -387,6 +401,7 @@ tests/test_webhook_hmac.py
387
401
  tests/test_whatsapp_importer.py
388
402
  tests/test_wiki_autopromote.py
389
403
  tests/test_wiki_binding.py
404
+ tests/test_wiki_engine_extra.py
390
405
  tests/test_wiki_engine_idempotency.py
391
406
  tests/test_wiki_explored_and_contradictions.py
392
407
  tests/test_wiki_freshness.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memorymaster"
7
- version = "3.25.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"}]
@@ -696,8 +696,9 @@ def call_claude_cli_judge(
696
696
  def answer_question(question: str, contexts: list[str], judge: JudgeClient) -> str:
697
697
  prompt = "\n\n".join(
698
698
  [
699
- "Answer the question using only the retrieved conversation context.",
700
- "If the context does not contain the answer, say I don't know.",
699
+ "Answer the question using the retrieved conversation context. "
700
+ "Answer with the most specific relevant fact from the retrieved context; "
701
+ "only say I don't know if the answer is genuinely absent.",
701
702
  "Keep the answer concise.",
702
703
  "Retrieved context:",
703
704
  "\n\n---\n\n".join(contexts),