memorymaster 3.15.1__tar.gz → 3.16.0__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 (364) hide show
  1. {memorymaster-3.15.1/memorymaster.egg-info → memorymaster-3.16.0}/PKG-INFO +1 -1
  2. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config.py +25 -5
  3. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/retrieval.py +74 -4
  4. {memorymaster-3.15.1 → memorymaster-3.16.0/memorymaster.egg-info}/PKG-INFO +1 -1
  5. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster.egg-info/SOURCES.txt +2 -0
  6. {memorymaster-3.15.1 → memorymaster-3.16.0}/pyproject.toml +1 -1
  7. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_config.py +7 -1
  8. memorymaster-3.16.0/tests/test_retrieval_rrf_tiebreaker.py +84 -0
  9. memorymaster-3.16.0/tests/test_retrieval_weights.py +69 -0
  10. {memorymaster-3.15.1 → memorymaster-3.16.0}/LICENSE +0 -0
  11. {memorymaster-3.15.1 → memorymaster-3.16.0}/README.md +0 -0
  12. {memorymaster-3.15.1 → memorymaster-3.16.0}/artifacts/bm25-per-field-eval-harness.py +0 -0
  13. {memorymaster-3.15.1 → memorymaster-3.16.0}/benchmarks/longmemeval_runner.py +0 -0
  14. {memorymaster-3.15.1 → memorymaster-3.16.0}/benchmarks/longmemeval_vector_runner.py +0 -0
  15. {memorymaster-3.15.1 → memorymaster-3.16.0}/benchmarks/perf_smoke.py +0 -0
  16. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/__init__.py +0 -0
  17. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/__main__.py +0 -0
  18. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/_storage_lifecycle.py +0 -0
  19. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/_storage_read.py +0 -0
  20. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/_storage_schema.py +0 -0
  21. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/_storage_shared.py +0 -0
  22. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/_storage_sources.py +0 -0
  23. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/_storage_write_claims.py +0 -0
  24. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/access_control.py +0 -0
  25. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/action_exporters.py +0 -0
  26. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/action_extractor.py +0 -0
  27. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/atlas_claim_extractor.py +0 -0
  28. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/atlas_contract.py +0 -0
  29. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/auto_extractor.py +0 -0
  30. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/auto_resolver.py +0 -0
  31. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/candidate_dedupe.py +0 -0
  32. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/claim_edges.py +0 -0
  33. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/claim_verifier.py +0 -0
  34. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/cli.py +0 -0
  35. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/cli_handlers_basic.py +0 -0
  36. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/cli_handlers_curation.py +0 -0
  37. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/cli_helpers.py +0 -0
  38. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/closets.py +0 -0
  39. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/claude-md-append.md +0 -0
  40. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/codex-agents-md-append.md +0 -0
  41. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-auto-ingest.py +0 -0
  42. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-classify.py +0 -0
  43. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-dream-sync.py +0 -0
  44. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-precompact.py +0 -0
  45. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-recall.py +0 -0
  46. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-session-start.py +0 -0
  47. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-steward-cycle.py +0 -0
  48. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-validate-wiki.py +0 -0
  49. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/conflict_resolver.py +0 -0
  50. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/connectors/__init__.py +0 -0
  51. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/connectors/whatsapp.py +0 -0
  52. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/context_hook.py +0 -0
  53. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/context_optimizer.py +0 -0
  54. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/daily_notes.py +0 -0
  55. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/dashboard.py +0 -0
  56. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/db_merge.py +0 -0
  57. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/dream_bridge.py +0 -0
  58. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/embeddings.py +0 -0
  59. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/entity_extractor.py +0 -0
  60. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/entity_graph.py +0 -0
  61. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/entity_registry.py +0 -0
  62. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/federated_graphify.py +0 -0
  63. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/feedback.py +0 -0
  64. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/graph_store.py +0 -0
  65. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/hook_log.py +0 -0
  66. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/__init__.py +0 -0
  67. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/calibration.py +0 -0
  68. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/compact_summaries.py +0 -0
  69. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/compactor.py +0 -0
  70. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/decay.py +0 -0
  71. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/dedup.py +0 -0
  72. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/deterministic.py +0 -0
  73. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/entity_graph_export.py +0 -0
  74. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/extractor.py +0 -0
  75. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/staleness.py +0 -0
  76. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/jobs/validator.py +0 -0
  77. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/key_rotator.py +0 -0
  78. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/lifecycle.py +0 -0
  79. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/llm_provider.py +0 -0
  80. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/llm_rerank.py +0 -0
  81. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/llm_steward.py +0 -0
  82. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/mcp_server.py +0 -0
  83. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/mcp_usage.py +0 -0
  84. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/media_processing.py +0 -0
  85. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/media_providers.py +0 -0
  86. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/metrics_exporter.py +0 -0
  87. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/models.py +0 -0
  88. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/observability.py +0 -0
  89. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/operator.py +0 -0
  90. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/operator_queue.py +0 -0
  91. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/plugins.py +0 -0
  92. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/policy.py +0 -0
  93. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/postgres_store.py +0 -0
  94. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/qdrant_backend.py +0 -0
  95. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/qdrant_recall_fallback.py +0 -0
  96. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/qmd_bridge.py +0 -0
  97. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/query_classifier.py +0 -0
  98. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/query_expansion.py +0 -0
  99. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/recall_fusion.py +0 -0
  100. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/recall_tokenizer.py +0 -0
  101. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/retry.py +0 -0
  102. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/review.py +0 -0
  103. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/rl_trainer.py +0 -0
  104. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/scheduler.py +0 -0
  105. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/schema.py +0 -0
  106. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/schema.sql +0 -0
  107. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/schema_postgres.sql +0 -0
  108. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/scope_utils.py +0 -0
  109. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/security.py +0 -0
  110. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/service.py +0 -0
  111. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/session_tracker.py +0 -0
  112. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/setup_hooks.py +0 -0
  113. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/skill_evolver.py +0 -0
  114. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/snapshot.py +0 -0
  115. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/steward.py +0 -0
  116. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/steward_classifier.py +0 -0
  117. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/steward_features.py +0 -0
  118. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/storage.py +0 -0
  119. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/store_factory.py +0 -0
  120. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/transcript_miner.py +0 -0
  121. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/turn_schema.py +0 -0
  122. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/vault_bases.py +0 -0
  123. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/vault_curator.py +0 -0
  124. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/vault_exporter.py +0 -0
  125. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/vault_linter.py +0 -0
  126. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/vault_log.py +0 -0
  127. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/vault_query_capture.py +0 -0
  128. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/vault_synthesis.py +0 -0
  129. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/verbatim_recall.py +0 -0
  130. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/verbatim_store.py +0 -0
  131. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/webhook.py +0 -0
  132. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/wiki_engine.py +0 -0
  133. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/wiki_freshness.py +0 -0
  134. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/wiki_similarity.py +0 -0
  135. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/wiki_suggest.py +0 -0
  136. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster/wiki_validate.py +0 -0
  137. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster.egg-info/dependency_links.txt +0 -0
  138. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster.egg-info/entry_points.txt +0 -0
  139. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster.egg-info/requires.txt +0 -0
  140. {memorymaster-3.15.1 → memorymaster-3.16.0}/memorymaster.egg-info/top_level.txt +0 -0
  141. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/agg_recall_latency.py +0 -0
  142. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/alert_operator_metrics.py +0 -0
  143. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/audit_dedupe_precision.py +0 -0
  144. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/autoresearch_daemon.py +0 -0
  145. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/backfill_entity_extraction.py +0 -0
  146. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/backfill_graph_store.py +0 -0
  147. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/backfill_stop_hook_citations.py +0 -0
  148. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/backtest_steward_classifier.py +0 -0
  149. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/build_steward_training_set.py +0 -0
  150. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/check_hook_template_drift.py +0 -0
  151. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/claude_to_turns.py +0 -0
  152. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/codex_live_to_turns.py +0 -0
  153. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/compaction_edge_cases.py +0 -0
  154. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/compaction_trace_report.py +0 -0
  155. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/compaction_trace_validate.py +0 -0
  156. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/confusion_matrix_eval.py +0 -0
  157. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/conversation_importer.py +0 -0
  158. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/conversation_to_turns.py +0 -0
  159. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/e2e_operator.py +0 -0
  160. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/email_live_to_turns.py +0 -0
  161. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/eval_bm25_sweep.py +0 -0
  162. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/eval_classify_f1.py +0 -0
  163. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/eval_memorymaster.py +0 -0
  164. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/eval_recall_precision_at_5.py +0 -0
  165. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/eval_recall_quality.py +0 -0
  166. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/eval_steward_pareto.py +0 -0
  167. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/eval_verbatim_recall.py +0 -0
  168. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/expand_recall_eval.py +0 -0
  169. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/generate_drill_signoff.py +0 -0
  170. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/git_to_turns.py +0 -0
  171. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/github_live_to_turns.py +0 -0
  172. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/gitnexus_to_claims.py +0 -0
  173. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/grid_recall_weights.py +0 -0
  174. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/index_claims_to_qdrant.py +0 -0
  175. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/ingest_planning_docs.py +0 -0
  176. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/jira_live_to_turns.py +0 -0
  177. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/label_prompts_with_judge.py +0 -0
  178. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/llm_benchmark.py +0 -0
  179. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/measure_dedupe_thresholds.py +0 -0
  180. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/merge_scope_variants.py +0 -0
  181. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/messages_to_turns.py +0 -0
  182. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/operator_metrics.py +0 -0
  183. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/precompute_candidates.py +0 -0
  184. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/recurring_incident_drill.py +0 -0
  185. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/release_readiness.py +0 -0
  186. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/run_codex_autologger.py +0 -0
  187. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/run_incident_drill.py +0 -0
  188. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/scheduled_ingest.py +0 -0
  189. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/setup-hooks.py +0 -0
  190. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/slack_live_to_turns.py +0 -0
  191. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/sync_hook_templates.py +0 -0
  192. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/tickets_to_turns.py +0 -0
  193. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/train_steward_classifier.py +0 -0
  194. {memorymaster-3.15.1 → memorymaster-3.16.0}/scripts/webhook_to_turns.py +0 -0
  195. {memorymaster-3.15.1 → memorymaster-3.16.0}/setup.cfg +0 -0
  196. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/bench_longmemeval.py +0 -0
  197. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/conftest.py +0 -0
  198. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/integration/test_extract_llm_ollama_live.py +0 -0
  199. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_access_control.py +0 -0
  200. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_action_exporters.py +0 -0
  201. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_action_extractor.py +0 -0
  202. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_atlas_claim_extractor.py +0 -0
  203. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_atlas_contract.py +0 -0
  204. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_atlas_source_schema.py +0 -0
  205. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_auto_extractor.py +0 -0
  206. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_auto_ingest_hook_citations.py +0 -0
  207. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_auto_ingest_hook_schema.py +0 -0
  208. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_auto_resolver.py +0 -0
  209. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_auto_validate.py +0 -0
  210. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_bm25_per_field.py +0 -0
  211. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_calibration.py +0 -0
  212. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_calibration_priors_applied.py +0 -0
  213. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_candidate_dedupe.py +0 -0
  214. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_claim_edges.py +0 -0
  215. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_claim_links.py +0 -0
  216. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_claim_type_ranking.py +0 -0
  217. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_classify_hook_f1.py +0 -0
  218. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_classify_hook_latency.py +0 -0
  219. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_claude_to_turns.py +0 -0
  220. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_cli_dry_run.py +0 -0
  221. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_cli_json_flag.py +0 -0
  222. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_cli_ready.py +0 -0
  223. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_cli_review_queue.py +0 -0
  224. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_cli_subcommands.py +0 -0
  225. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_closets.py +0 -0
  226. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_closets_recall_integration.py +0 -0
  227. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_compact_summaries.py +0 -0
  228. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_compact_summaries_sensitivity.py +0 -0
  229. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_compaction_trace.py +0 -0
  230. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_compactor_artifact_order.py +0 -0
  231. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_conflict_resolver.py +0 -0
  232. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_confusion_matrix_eval.py +0 -0
  233. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_connection_retry.py +0 -0
  234. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_connectors.py +0 -0
  235. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_context_hook.py +0 -0
  236. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_context_optimizer.py +0 -0
  237. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_context_optimizer_provider.py +0 -0
  238. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_conversation_to_turns.py +0 -0
  239. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dashboard.py +0 -0
  240. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dashboard_coverage.py +0 -0
  241. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dashboard_latency.py +0 -0
  242. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dashboard_lineage.py +0 -0
  243. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dashboard_review_queue.py +0 -0
  244. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_db_merge_confidence_conflict.py +0 -0
  245. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_db_merge_coverage_v2.py +0 -0
  246. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_decay_coverage.py +0 -0
  247. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_decay_respects_pinned.py +0 -0
  248. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dedup.py +0 -0
  249. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dedup_cli.py +0 -0
  250. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dedup_conflict_disambiguation.py +0 -0
  251. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_deterministic_predicates.py +0 -0
  252. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dream_bridge_coverage_v2.py +0 -0
  253. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_dream_bridge_sensitivity.py +0 -0
  254. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_embeddings_coverage.py +0 -0
  255. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_entity_extractor.py +0 -0
  256. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_entity_extractor_llm.py +0 -0
  257. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_entity_graph.py +0 -0
  258. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_entity_graph_export.py +0 -0
  259. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_entity_new_kinds.py +0 -0
  260. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_entity_regex_v3.py +0 -0
  261. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_entity_registry.py +0 -0
  262. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_eval_harness.py +0 -0
  263. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_events_schema.py +0 -0
  264. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_extract_llm_ollama.py +0 -0
  265. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_federated_graphify_mcp.py +0 -0
  266. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_federated_query_safety.py +0 -0
  267. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_feedback.py +0 -0
  268. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_fts5_search.py +0 -0
  269. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_graph_distance.py +0 -0
  270. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_graph_store.py +0 -0
  271. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_handler_regressions.py +0 -0
  272. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_hook_env_isolation.py +0 -0
  273. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_human_id.py +0 -0
  274. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_incident_drill_runner.py +0 -0
  275. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_integration_workflows.py +0 -0
  276. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_key_rotator.py +0 -0
  277. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_lifecycle.py +0 -0
  278. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_lifecycle_supersede_invariant.py +0 -0
  279. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_llm_fallback.py +0 -0
  280. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_llm_provider_claude_cli.py +0 -0
  281. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_llm_provider_key_rotation.py +0 -0
  282. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_llm_steward_coverage.py +0 -0
  283. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_llm_steward_key_rotation.py +0 -0
  284. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_mcp_filter_bypass.py +0 -0
  285. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_mcp_helpers.py +0 -0
  286. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_mcp_rate_limit.py +0 -0
  287. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_mcp_server_validation.py +0 -0
  288. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_mcp_usage.py +0 -0
  289. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_media_processing.py +0 -0
  290. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_meta_decisions.py +0 -0
  291. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_metrics_exporter.py +0 -0
  292. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_observability.py +0 -0
  293. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_obsidian_mind_patterns.py +0 -0
  294. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_operator.py +0 -0
  295. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_operator_queue.py +0 -0
  296. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_perf_smoke_config.py +0 -0
  297. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_plugins.py +0 -0
  298. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_policy_coverage.py +0 -0
  299. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_policy_mode_env.py +0 -0
  300. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_postgres_parity.py +0 -0
  301. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_qdrant_backend.py +0 -0
  302. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_qmd_bridge.py +0 -0
  303. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_query_classifier.py +0 -0
  304. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_query_expansion.py +0 -0
  305. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_recall_entity_fanout.py +0 -0
  306. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_recall_fusion.py +0 -0
  307. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_recall_latency.py +0 -0
  308. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_recall_precision_at_5.py +0 -0
  309. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_recall_tokenizer.py +0 -0
  310. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_recall_vector_fallback.py +0 -0
  311. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_reliability_hardening.py +0 -0
  312. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_resolvers_concurrent_supersede.py +0 -0
  313. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_retrieval_profile.py +0 -0
  314. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_review.py +0 -0
  315. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_rl_trainer.py +0 -0
  316. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_rrf_auto_gate.py +0 -0
  317. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_scheduler.py +0 -0
  318. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_schema.py +0 -0
  319. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_scope_boost.py +0 -0
  320. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_scope_utils.py +0 -0
  321. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_security_access.py +0 -0
  322. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_security_patterns.py +0 -0
  323. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_sensitivity_filter_adversarial.py +0 -0
  324. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_sensitivity_filter_adversarial_v2.py +0 -0
  325. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_sensitivity_filter_t07.py +0 -0
  326. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_service_coverage.py +0 -0
  327. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_session_tracker.py +0 -0
  328. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_snapshot.py +0 -0
  329. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_snapshot_roundtrip.py +0 -0
  330. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_sqlite_core.py +0 -0
  331. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_staleness.py +0 -0
  332. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_stealth_mode.py +0 -0
  333. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_steward.py +0 -0
  334. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_steward_classifier.py +0 -0
  335. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_steward_features.py +0 -0
  336. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_steward_features_v3.py +0 -0
  337. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_steward_resolution_parity.py +0 -0
  338. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_storage_parity.py +0 -0
  339. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_store_factory.py +0 -0
  340. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_tenant_isolation.py +0 -0
  341. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_turn_schema.py +0 -0
  342. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_two_pass_recall.py +0 -0
  343. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_v311_fixes.py +0 -0
  344. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_v313_e2e.py +0 -0
  345. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_v313_run_cycle_dedupe.py +0 -0
  346. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_v390_e2e.py +0 -0
  347. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_v391_strict_warnings.py +0 -0
  348. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_vault_exporter.py +0 -0
  349. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_vault_linter_orphan.py +0 -0
  350. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_vector_search.py +0 -0
  351. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_verbatim_dedup.py +0 -0
  352. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_verbatim_recall.py +0 -0
  353. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_verbatim_store.py +0 -0
  354. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_verbatim_store_qdrant.py +0 -0
  355. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_webhook.py +0 -0
  356. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_whatsapp_importer.py +0 -0
  357. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_wiki_autopromote.py +0 -0
  358. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_wiki_binding.py +0 -0
  359. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_wiki_engine_idempotency.py +0 -0
  360. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_wiki_explored_and_contradictions.py +0 -0
  361. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_wiki_freshness.py +0 -0
  362. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_wiki_similarity_multiscope.py +0 -0
  363. {memorymaster-3.15.1 → memorymaster-3.16.0}/tests/test_wiki_suggest.py +0 -0
  364. {memorymaster-3.15.1 → memorymaster-3.16.0}/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.15.1
3
+ Version: 3.16.0
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
@@ -8,7 +8,11 @@ Environment variables
8
8
  ---------------------
9
9
  MEMORYMASTER_RETRIEVAL_WEIGHTS
10
10
  Comma-separated floats for hybrid ranking: lexical,confidence,freshness,vector.
11
- Default: ``0.45,0.30,0.15,0.10``
11
+ Default: ``0.30,0.20,0.10,0.40``
12
+
13
+ MEMORYMASTER_W_LEX, MEMORYMASTER_W_CONF, MEMORYMASTER_W_FRESH, MEMORYMASTER_W_VEC
14
+ Individual overrides for the four hybrid ranking weights. These take
15
+ precedence over ``MEMORYMASTER_RETRIEVAL_WEIGHTS`` when set.
12
16
 
13
17
  MEMORYMASTER_RETRIEVAL_WEIGHTS_NO_VECTOR
14
18
  Weights when vector search is disabled: lexical,confidence,freshness.
@@ -55,6 +59,14 @@ MEMORYMASTER_LLM_RERANK
55
59
  Enable Gemini cross-encoder reranking over the top retrieval candidates.
56
60
  Default: ``0``
57
61
 
62
+ MEMORYMASTER_RRF_TIEBREAKER
63
+ Enable RRF near-tie reordering after linear retrieval ranking.
64
+ Default: ``0``
65
+
66
+ MEMORYMASTER_RRF_TIEBREAKER_THRESHOLD
67
+ Maximum adjacent score gap considered a near tie.
68
+ Default: ``0.01``
69
+
58
70
  MEMORYMASTER_CONFIG_FILE
59
71
  Path to a JSON config file. Keys match attribute names on ``Config``.
60
72
  """
@@ -159,10 +171,10 @@ class Config:
159
171
  """Immutable configuration for tunable MemoryMaster constants."""
160
172
 
161
173
  # --- Retrieval ranking weights (hybrid mode with vector) ---
162
- retrieval_weight_lexical: float = 0.45
163
- retrieval_weight_confidence: float = 0.30
164
- retrieval_weight_freshness: float = 0.15
165
- retrieval_weight_vector: float = 0.10
174
+ retrieval_weight_lexical: float = 0.30
175
+ retrieval_weight_confidence: float = 0.20
176
+ retrieval_weight_freshness: float = 0.10
177
+ retrieval_weight_vector: float = 0.40
166
178
 
167
179
  # --- Retrieval ranking weights (hybrid mode without vector) ---
168
180
  retrieval_weight_lexical_no_vector: float = 0.55
@@ -197,6 +209,8 @@ class Config:
197
209
  pinned_bonus: float = 0.03
198
210
  session_diversity_cap: int = 3
199
211
  llm_rerank: bool = False
212
+ rrf_tiebreaker_enabled: bool = False
213
+ rrf_tiebreaker_threshold: float = 0.01
200
214
 
201
215
  # --- Initial confidence priors calibrated from validator outcomes ---
202
216
  default_initial_confidence: float = DEFAULT_INITIAL_CONFIDENCE
@@ -310,6 +324,10 @@ def load_config(config_path: str | Path | None = None) -> Config:
310
324
  "retrieval_weight_freshness",
311
325
  "retrieval_weight_vector",
312
326
  ])
327
+ _apply_env_float(overrides, "MEMORYMASTER_W_LEX", "retrieval_weight_lexical")
328
+ _apply_env_float(overrides, "MEMORYMASTER_W_CONF", "retrieval_weight_confidence")
329
+ _apply_env_float(overrides, "MEMORYMASTER_W_FRESH", "retrieval_weight_freshness")
330
+ _apply_env_float(overrides, "MEMORYMASTER_W_VEC", "retrieval_weight_vector")
313
331
  _apply_env_floats(overrides, "MEMORYMASTER_RETRIEVAL_WEIGHTS_NO_VECTOR", 3, [
314
332
  "retrieval_weight_lexical_no_vector",
315
333
  "retrieval_weight_confidence_no_vector",
@@ -343,6 +361,8 @@ def load_config(config_path: str | Path | None = None) -> Config:
343
361
  _apply_env_float(overrides, "MEMORYMASTER_PINNED_BONUS", "pinned_bonus")
344
362
  _apply_env_int(overrides, "MEMORYMASTER_SESSION_DIVERSITY_CAP", "session_diversity_cap")
345
363
  _apply_env_bool(overrides, "MEMORYMASTER_LLM_RERANK", "llm_rerank")
364
+ _apply_env_bool(overrides, "MEMORYMASTER_RRF_TIEBREAKER", "rrf_tiebreaker_enabled")
365
+ _apply_env_float(overrides, "MEMORYMASTER_RRF_TIEBREAKER_THRESHOLD", "rrf_tiebreaker_threshold")
346
366
 
347
367
  # Filter to only valid Config fields
348
368
  valid_fields = {f.name for f in Config.__dataclass_fields__.values()}
@@ -8,6 +8,7 @@ from typing import Callable, Mapping
8
8
 
9
9
  from memorymaster.config import get_config
10
10
  from memorymaster.models import Claim
11
+ from memorymaster.recall_fusion import RRF_K_DEFAULT, rrf_fuse
11
12
 
12
13
  RETRIEVAL_MODES = ("legacy", "hybrid")
13
14
 
@@ -136,12 +137,12 @@ def rank_claims(
136
137
  def _compute_claim_score(claim: Claim, lexical: float, confidence: float, freshness: float, vector: float, vector_enabled: bool, semantic_vectors: bool) -> float:
137
138
  """Compute relevance score for a claim."""
138
139
  cfg = get_config()
140
+ w_l, w_c, w_f, w_v = cfg.retrieval_weights
139
141
  if vector_enabled and semantic_vectors:
140
- # Real semantic embeddings: vector is the primary relevance signal
141
- score = (0.30 * lexical) + (0.20 * confidence) + (0.10 * freshness) + (0.40 * vector)
142
+ # Real semantic embeddings use the same configurable blend as other
143
+ # vector-enabled ranking so env sweeps affect both paths.
144
+ score = (w_l * lexical) + (w_c * confidence) + (w_f * freshness) + (w_v * vector)
142
145
  elif vector_enabled:
143
- # Hash-based vectors: limited semantic value, keep lexical dominant
144
- w_l, w_c, w_f, w_v = cfg.retrieval_weights
145
146
  score = (w_l * lexical) + (w_c * confidence) + (w_f * freshness) + (w_v * vector)
146
147
  else:
147
148
  w_l, w_c, w_f = cfg.retrieval_weights_no_vector
@@ -180,6 +181,69 @@ def apply_session_diversity_cap(ranked: list[RankedClaim], cap: int) -> list[Ran
180
181
  return result
181
182
 
182
183
 
184
+ def _component_rankings(rows: list[RankedClaim]) -> dict[str, list[int]]:
185
+ original_positions = {row.claim.id: index for index, row in enumerate(rows)}
186
+
187
+ def ranked_ids(score_attr: str) -> list[int]:
188
+ ordered = sorted(
189
+ rows,
190
+ key=lambda row: (
191
+ -float(getattr(row, score_attr)),
192
+ original_positions[row.claim.id],
193
+ ),
194
+ )
195
+ return [row.claim.id for row in ordered]
196
+
197
+ return {
198
+ "lexical": ranked_ids("lexical_score"),
199
+ "vector": ranked_ids("vector_score"),
200
+ "confidence": ranked_ids("confidence_score"),
201
+ "freshness": ranked_ids("freshness_score"),
202
+ }
203
+
204
+
205
+ def apply_rrf_tiebreaker(
206
+ ranked: list[RankedClaim],
207
+ *,
208
+ threshold: float = 0.01,
209
+ k: int = RRF_K_DEFAULT,
210
+ enabled: bool = True,
211
+ ) -> list[RankedClaim]:
212
+ if not enabled or len(ranked) < 2:
213
+ return ranked
214
+
215
+ threshold = max(0.0, threshold)
216
+ threshold_epsilon = 1e-12
217
+ head_count = min(10, len(ranked))
218
+ result = list(ranked)
219
+ index = 0
220
+
221
+ while index < head_count:
222
+ group_end = index + 1
223
+ while (
224
+ group_end < head_count
225
+ and abs(ranked[group_end - 1].score - ranked[group_end].score)
226
+ <= threshold + threshold_epsilon
227
+ ):
228
+ group_end += 1
229
+
230
+ if group_end - index > 1:
231
+ group = ranked[index:group_end]
232
+ original_positions = {row.claim.id: offset for offset, row in enumerate(group)}
233
+ rrf_scores = rrf_fuse(_component_rankings(group), k=k)
234
+ result[index:group_end] = sorted(
235
+ group,
236
+ key=lambda row: (
237
+ -rrf_scores.get(row.claim.id, 0.0),
238
+ original_positions[row.claim.id],
239
+ ),
240
+ )
241
+
242
+ index = group_end
243
+
244
+ return result
245
+
246
+
183
247
  def rank_claim_rows(
184
248
  query_text: str,
185
249
  claims: list[Claim],
@@ -262,5 +326,11 @@ def rank_claim_rows(
262
326
  ),
263
327
  reverse=True,
264
328
  )
329
+ cfg = get_config()
330
+ ranked = apply_rrf_tiebreaker(
331
+ ranked,
332
+ threshold=cfg.rrf_tiebreaker_threshold,
333
+ enabled=cfg.rrf_tiebreaker_enabled,
334
+ )
265
335
  ranked = apply_session_diversity_cap(ranked, get_config().session_diversity_cap)
266
336
  return ranked[:limit]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memorymaster
3
- Version: 3.15.1
3
+ Version: 3.16.0
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
@@ -306,6 +306,8 @@ tests/test_recall_vector_fallback.py
306
306
  tests/test_reliability_hardening.py
307
307
  tests/test_resolvers_concurrent_supersede.py
308
308
  tests/test_retrieval_profile.py
309
+ tests/test_retrieval_rrf_tiebreaker.py
310
+ tests/test_retrieval_weights.py
309
311
  tests/test_review.py
310
312
  tests/test_rl_trainer.py
311
313
  tests/test_rrf_auto_gate.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memorymaster"
7
- version = "3.15.1"
7
+ version = "3.16.0"
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"}]
@@ -22,7 +22,7 @@ def _reset():
22
22
  class TestConfigDefaults:
23
23
  def test_default_retrieval_weights(self):
24
24
  cfg = Config()
25
- assert cfg.retrieval_weights == (0.45, 0.30, 0.15, 0.10)
25
+ assert cfg.retrieval_weights == (0.30, 0.20, 0.10, 0.40)
26
26
 
27
27
  def test_default_no_vector_weights(self):
28
28
  cfg = Config()
@@ -58,6 +58,12 @@ class TestConfigEnvOverrides:
58
58
  cfg = load_config()
59
59
  assert cfg.retrieval_weights == (0.40, 0.25, 0.20, 0.15)
60
60
 
61
+ def test_individual_retrieval_weight_env(self, monkeypatch):
62
+ monkeypatch.setenv("MEMORYMASTER_RETRIEVAL_WEIGHTS", "0.40,0.25,0.20,0.15")
63
+ monkeypatch.setenv("MEMORYMASTER_W_LEX", "0.55")
64
+ cfg = load_config()
65
+ assert cfg.retrieval_weights == (0.55, 0.25, 0.20, 0.15)
66
+
61
67
  def test_retrieval_weights_no_vector_env(self, monkeypatch):
62
68
  monkeypatch.setenv("MEMORYMASTER_RETRIEVAL_WEIGHTS_NO_VECTOR", "0.60,0.25,0.15")
63
69
  cfg = load_config()
@@ -0,0 +1,84 @@
1
+ from __future__ import annotations
2
+
3
+ from memorymaster.config import get_config, reset_config
4
+ from memorymaster.models import Claim
5
+ from memorymaster.retrieval import RankedClaim, apply_rrf_tiebreaker
6
+
7
+
8
+ def _claim(claim_id: int) -> Claim:
9
+ return Claim(
10
+ id=claim_id,
11
+ text=f"claim {claim_id}",
12
+ idempotency_key=None,
13
+ normalized_text=None,
14
+ claim_type=None,
15
+ subject=None,
16
+ predicate=None,
17
+ object_value=None,
18
+ scope="project",
19
+ volatility="medium",
20
+ status="confirmed",
21
+ confidence=0.8,
22
+ pinned=False,
23
+ supersedes_claim_id=None,
24
+ replaced_by_claim_id=None,
25
+ created_at="2026-03-01T00:00:00+00:00",
26
+ updated_at="2026-03-08T00:00:00+00:00",
27
+ last_validated_at=None,
28
+ archived_at=None,
29
+ )
30
+
31
+
32
+ def _row(
33
+ claim_id: int,
34
+ *,
35
+ score: float,
36
+ lexical: float,
37
+ vector: float,
38
+ confidence: float,
39
+ freshness: float,
40
+ ) -> RankedClaim:
41
+ return RankedClaim(
42
+ claim=_claim(claim_id),
43
+ score=score,
44
+ lexical_score=lexical,
45
+ vector_score=vector,
46
+ confidence_score=confidence,
47
+ freshness_score=freshness,
48
+ )
49
+
50
+
51
+ def test_clear_winner_pair_unchanged() -> None:
52
+ rows = [
53
+ _row(1, score=0.8, lexical=0.1, vector=0.1, confidence=0.1, freshness=0.1),
54
+ _row(2, score=0.5, lexical=1.0, vector=1.0, confidence=1.0, freshness=1.0),
55
+ ]
56
+
57
+ result = apply_rrf_tiebreaker(rows, threshold=0.01, enabled=True)
58
+
59
+ assert [row.claim.id for row in result] == [1, 2]
60
+
61
+
62
+ def test_near_tie_reordered_by_rrf() -> None:
63
+ rows = [
64
+ _row(1, score=0.81, lexical=1.0, vector=0.0, confidence=0.0, freshness=0.0),
65
+ _row(2, score=0.80, lexical=0.9, vector=1.0, confidence=1.0, freshness=1.0),
66
+ ]
67
+
68
+ result = apply_rrf_tiebreaker(rows, threshold=0.01, enabled=True)
69
+
70
+ assert [row.claim.id for row in result] == [2, 1]
71
+
72
+
73
+ def test_disabled_flag_no_op(monkeypatch) -> None:
74
+ monkeypatch.setenv("MEMORYMASTER_RRF_TIEBREAKER", "0")
75
+ reset_config()
76
+ rows = [
77
+ _row(1, score=0.81, lexical=1.0, vector=0.0, confidence=0.0, freshness=0.0),
78
+ _row(2, score=0.80, lexical=0.9, vector=1.0, confidence=1.0, freshness=1.0),
79
+ ]
80
+
81
+ result = apply_rrf_tiebreaker(rows, threshold=0.01, enabled=get_config().rrf_tiebreaker_enabled)
82
+
83
+ assert [row.claim.id for row in result] == [1, 2]
84
+ reset_config()
@@ -0,0 +1,69 @@
1
+ from __future__ import annotations
2
+
3
+ import pytest
4
+
5
+ from memorymaster.config import reset_config
6
+ from memorymaster.models import Claim
7
+ from memorymaster.retrieval import rank_claim_rows
8
+
9
+
10
+ @pytest.fixture(autouse=True)
11
+ def _reset_config():
12
+ reset_config()
13
+ yield
14
+ reset_config()
15
+
16
+
17
+ def _claim() -> Claim:
18
+ return Claim(
19
+ id=1,
20
+ text="alpha beta retrieval target",
21
+ idempotency_key=None,
22
+ normalized_text=None,
23
+ claim_type=None,
24
+ subject=None,
25
+ predicate=None,
26
+ object_value=None,
27
+ scope="project",
28
+ volatility="medium",
29
+ status="confirmed",
30
+ confidence=0.8,
31
+ pinned=False,
32
+ supersedes_claim_id=None,
33
+ replaced_by_claim_id=None,
34
+ created_at="2999-01-01T00:00:00+00:00",
35
+ updated_at="2999-01-01T00:00:00+00:00",
36
+ last_validated_at=None,
37
+ archived_at=None,
38
+ )
39
+
40
+
41
+ def _row(*, semantic_vectors: bool):
42
+ def vector_hook(query, claims):
43
+ return {claim.id: 0.6 for claim in claims}
44
+
45
+ return rank_claim_rows(
46
+ "alpha beta",
47
+ [_claim()],
48
+ mode="hybrid",
49
+ limit=1,
50
+ vector_hook=vector_hook,
51
+ semantic_vectors=semantic_vectors,
52
+ )[0]
53
+
54
+
55
+ def test_memorymaster_w_lex_affects_vector_enabled_ranking_paths(monkeypatch):
56
+ default_lexical = _row(semantic_vectors=False)
57
+ default_semantic = _row(semantic_vectors=True)
58
+
59
+ monkeypatch.setenv("MEMORYMASTER_W_LEX", "0.55")
60
+ reset_config()
61
+
62
+ override_lexical = _row(semantic_vectors=False)
63
+ override_semantic = _row(semantic_vectors=True)
64
+ expected_delta = (0.55 - 0.30) * default_lexical.lexical_score
65
+
66
+ assert override_lexical.score - default_lexical.score == pytest.approx(expected_delta)
67
+ assert override_semantic.score - default_semantic.score == pytest.approx(expected_delta)
68
+ assert override_lexical.score != default_lexical.score
69
+ assert override_semantic.score != default_semantic.score
File without changes
File without changes