memorymaster 3.12.0__tar.gz → 3.13.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 (319) hide show
  1. {memorymaster-3.12.0 → memorymaster-3.13.0}/PKG-INFO +7 -6
  2. {memorymaster-3.12.0 → memorymaster-3.13.0}/README.md +6 -5
  3. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/_storage_schema.py +145 -0
  4. memorymaster-3.13.0/memorymaster/_storage_sources.py +979 -0
  5. memorymaster-3.13.0/memorymaster/action_exporters.py +91 -0
  6. memorymaster-3.13.0/memorymaster/action_extractor.py +212 -0
  7. memorymaster-3.13.0/memorymaster/atlas_claim_extractor.py +162 -0
  8. memorymaster-3.13.0/memorymaster/atlas_contract.py +381 -0
  9. memorymaster-3.13.0/memorymaster/candidate_dedupe.py +288 -0
  10. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/cli.py +84 -0
  11. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/cli_handlers_basic.py +469 -1
  12. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/cli_handlers_curation.py +32 -0
  13. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/cli_helpers.py +15 -2
  14. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/hooks/memorymaster-auto-ingest.py +23 -6
  15. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/hooks/memorymaster-precompact.py +30 -1
  16. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/hooks/memorymaster-steward-cycle.py +7 -0
  17. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/hooks/memorymaster-validate-wiki.py +1 -1
  18. memorymaster-3.13.0/memorymaster/connectors/__init__.py +2 -0
  19. memorymaster-3.13.0/memorymaster/connectors/whatsapp.py +235 -0
  20. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/context_hook.py +137 -2
  21. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/dashboard.py +42 -0
  22. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/compactor.py +9 -1
  23. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/decay.py +21 -1
  24. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/llm_provider.py +13 -0
  25. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/llm_steward.py +99 -7
  26. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/mcp_server.py +133 -0
  27. memorymaster-3.13.0/memorymaster/media_processing.py +199 -0
  28. memorymaster-3.13.0/memorymaster/media_providers.py +256 -0
  29. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/models.py +106 -0
  30. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/postgres_store.py +896 -0
  31. memorymaster-3.13.0/memorymaster/schema.sql +230 -0
  32. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/schema_postgres.sql +108 -0
  33. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/service.py +239 -1
  34. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/steward_classifier.py +5 -2
  35. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/steward_features.py +4 -5
  36. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/storage.py +3 -1
  37. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/verbatim_store.py +50 -11
  38. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/wiki_engine.py +90 -3
  39. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster.egg-info/PKG-INFO +7 -6
  40. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster.egg-info/SOURCES.txt +24 -1
  41. {memorymaster-3.12.0 → memorymaster-3.13.0}/pyproject.toml +1 -1
  42. memorymaster-3.13.0/scripts/audit_dedupe_precision.py +121 -0
  43. memorymaster-3.13.0/scripts/measure_dedupe_thresholds.py +114 -0
  44. memorymaster-3.13.0/tests/test_action_exporters.py +68 -0
  45. memorymaster-3.13.0/tests/test_action_extractor.py +77 -0
  46. memorymaster-3.13.0/tests/test_atlas_claim_extractor.py +61 -0
  47. memorymaster-3.13.0/tests/test_atlas_contract.py +1010 -0
  48. memorymaster-3.13.0/tests/test_atlas_source_schema.py +181 -0
  49. memorymaster-3.13.0/tests/test_candidate_dedupe.py +296 -0
  50. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_dashboard.py +46 -1
  51. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_graph_store.py +1 -0
  52. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_llm_provider_claude_cli.py +1 -1
  53. memorymaster-3.13.0/tests/test_media_processing.py +86 -0
  54. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_steward_classifier.py +2 -1
  55. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_steward_features_v3.py +3 -2
  56. memorymaster-3.13.0/tests/test_v313_e2e.py +265 -0
  57. memorymaster-3.13.0/tests/test_v313_run_cycle_dedupe.py +176 -0
  58. memorymaster-3.13.0/tests/test_verbatim_dedup.py +144 -0
  59. memorymaster-3.13.0/tests/test_whatsapp_importer.py +106 -0
  60. memorymaster-3.13.0/tests/test_wiki_explored_and_contradictions.py +229 -0
  61. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_wiki_similarity_multiscope.py +3 -1
  62. memorymaster-3.12.0/memorymaster/config_templates/hooks/memorymaster-observe.py +0 -39
  63. memorymaster-3.12.0/memorymaster/schema.sql +0 -123
  64. {memorymaster-3.12.0 → memorymaster-3.13.0}/LICENSE +0 -0
  65. {memorymaster-3.12.0 → memorymaster-3.13.0}/artifacts/bm25-per-field-eval-harness.py +0 -0
  66. {memorymaster-3.12.0 → memorymaster-3.13.0}/benchmarks/longmemeval_runner.py +0 -0
  67. {memorymaster-3.12.0 → memorymaster-3.13.0}/benchmarks/longmemeval_vector_runner.py +0 -0
  68. {memorymaster-3.12.0 → memorymaster-3.13.0}/benchmarks/perf_smoke.py +0 -0
  69. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/__init__.py +0 -0
  70. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/__main__.py +0 -0
  71. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/_storage_lifecycle.py +0 -0
  72. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/_storage_read.py +0 -0
  73. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/_storage_shared.py +0 -0
  74. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/_storage_write_claims.py +0 -0
  75. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/access_control.py +0 -0
  76. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/auto_extractor.py +0 -0
  77. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/auto_resolver.py +0 -0
  78. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/claim_edges.py +0 -0
  79. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/claim_verifier.py +0 -0
  80. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/closets.py +0 -0
  81. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config.py +0 -0
  82. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/claude-md-append.md +0 -0
  83. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/codex-agents-md-append.md +0 -0
  84. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/hooks/memorymaster-classify.py +0 -0
  85. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/hooks/memorymaster-dream-sync.py +0 -0
  86. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/hooks/memorymaster-recall.py +0 -0
  87. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/config_templates/hooks/memorymaster-session-start.py +0 -0
  88. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/conflict_resolver.py +0 -0
  89. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/context_optimizer.py +0 -0
  90. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/daily_notes.py +0 -0
  91. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/db_merge.py +0 -0
  92. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/dream_bridge.py +0 -0
  93. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/embeddings.py +0 -0
  94. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/entity_extractor.py +0 -0
  95. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/entity_graph.py +0 -0
  96. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/entity_registry.py +0 -0
  97. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/federated_graphify.py +0 -0
  98. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/feedback.py +0 -0
  99. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/graph_store.py +0 -0
  100. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/hook_log.py +0 -0
  101. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/__init__.py +0 -0
  102. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/compact_summaries.py +0 -0
  103. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/dedup.py +0 -0
  104. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/deterministic.py +0 -0
  105. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/extractor.py +0 -0
  106. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/staleness.py +0 -0
  107. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/jobs/validator.py +0 -0
  108. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/key_rotator.py +0 -0
  109. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/lifecycle.py +0 -0
  110. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/metrics_exporter.py +0 -0
  111. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/operator.py +0 -0
  112. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/operator_queue.py +0 -0
  113. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/plugins.py +0 -0
  114. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/policy.py +0 -0
  115. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/qdrant_backend.py +0 -0
  116. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/qdrant_recall_fallback.py +0 -0
  117. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/qmd_bridge.py +0 -0
  118. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/query_classifier.py +0 -0
  119. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/query_expansion.py +0 -0
  120. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/recall_fusion.py +0 -0
  121. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/recall_tokenizer.py +0 -0
  122. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/retrieval.py +0 -0
  123. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/retry.py +0 -0
  124. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/review.py +0 -0
  125. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/rl_trainer.py +0 -0
  126. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/scheduler.py +0 -0
  127. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/schema.py +0 -0
  128. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/scope_utils.py +0 -0
  129. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/security.py +0 -0
  130. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/session_tracker.py +0 -0
  131. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/setup_hooks.py +0 -0
  132. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/skill_evolver.py +0 -0
  133. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/snapshot.py +0 -0
  134. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/steward.py +0 -0
  135. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/store_factory.py +0 -0
  136. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/transcript_miner.py +0 -0
  137. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/turn_schema.py +0 -0
  138. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/vault_bases.py +0 -0
  139. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/vault_curator.py +0 -0
  140. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/vault_exporter.py +0 -0
  141. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/vault_linter.py +0 -0
  142. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/vault_log.py +0 -0
  143. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/vault_query_capture.py +0 -0
  144. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/vault_synthesis.py +0 -0
  145. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/verbatim_recall.py +0 -0
  146. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/webhook.py +0 -0
  147. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/wiki_freshness.py +0 -0
  148. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/wiki_similarity.py +0 -0
  149. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster/wiki_validate.py +0 -0
  150. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster.egg-info/dependency_links.txt +0 -0
  151. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster.egg-info/entry_points.txt +0 -0
  152. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster.egg-info/requires.txt +0 -0
  153. {memorymaster-3.12.0 → memorymaster-3.13.0}/memorymaster.egg-info/top_level.txt +0 -0
  154. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/agg_recall_latency.py +0 -0
  155. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/alert_operator_metrics.py +0 -0
  156. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/autoresearch_daemon.py +0 -0
  157. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/backfill_entity_extraction.py +0 -0
  158. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/backfill_graph_store.py +0 -0
  159. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/backfill_stop_hook_citations.py +0 -0
  160. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/backtest_steward_classifier.py +0 -0
  161. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/build_steward_training_set.py +0 -0
  162. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/check_hook_template_drift.py +0 -0
  163. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/claude_to_turns.py +0 -0
  164. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/codex_live_to_turns.py +0 -0
  165. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/compaction_edge_cases.py +0 -0
  166. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/compaction_trace_report.py +0 -0
  167. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/compaction_trace_validate.py +0 -0
  168. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/confusion_matrix_eval.py +0 -0
  169. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/conversation_importer.py +0 -0
  170. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/conversation_to_turns.py +0 -0
  171. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/e2e_operator.py +0 -0
  172. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/email_live_to_turns.py +0 -0
  173. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/eval_bm25_sweep.py +0 -0
  174. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/eval_classify_f1.py +0 -0
  175. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/eval_memorymaster.py +0 -0
  176. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/eval_recall_precision_at_5.py +0 -0
  177. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/eval_recall_quality.py +0 -0
  178. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/eval_steward_pareto.py +0 -0
  179. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/eval_verbatim_recall.py +0 -0
  180. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/expand_recall_eval.py +0 -0
  181. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/generate_drill_signoff.py +0 -0
  182. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/git_to_turns.py +0 -0
  183. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/github_live_to_turns.py +0 -0
  184. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/gitnexus_to_claims.py +0 -0
  185. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/grid_recall_weights.py +0 -0
  186. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/index_claims_to_qdrant.py +0 -0
  187. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/ingest_planning_docs.py +0 -0
  188. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/jira_live_to_turns.py +0 -0
  189. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/label_prompts_with_judge.py +0 -0
  190. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/llm_benchmark.py +0 -0
  191. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/merge_scope_variants.py +0 -0
  192. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/messages_to_turns.py +0 -0
  193. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/operator_metrics.py +0 -0
  194. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/precompute_candidates.py +0 -0
  195. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/recurring_incident_drill.py +0 -0
  196. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/release_readiness.py +0 -0
  197. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/run_codex_autologger.py +0 -0
  198. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/run_incident_drill.py +0 -0
  199. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/run_longmemeval.py +0 -0
  200. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/scheduled_ingest.py +0 -0
  201. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/setup-hooks.py +0 -0
  202. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/slack_live_to_turns.py +0 -0
  203. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/sync_hook_templates.py +0 -0
  204. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/tickets_to_turns.py +0 -0
  205. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/train_steward_classifier.py +0 -0
  206. {memorymaster-3.12.0 → memorymaster-3.13.0}/scripts/webhook_to_turns.py +0 -0
  207. {memorymaster-3.12.0 → memorymaster-3.13.0}/setup.cfg +0 -0
  208. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/conftest.py +0 -0
  209. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/integration/test_extract_llm_ollama_live.py +0 -0
  210. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_access_control.py +0 -0
  211. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_auto_extractor.py +0 -0
  212. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_auto_ingest_hook_citations.py +0 -0
  213. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_auto_ingest_hook_schema.py +0 -0
  214. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_auto_resolver.py +0 -0
  215. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_auto_validate.py +0 -0
  216. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_bm25_per_field.py +0 -0
  217. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_claim_edges.py +0 -0
  218. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_claim_links.py +0 -0
  219. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_claim_type_ranking.py +0 -0
  220. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_classify_hook_f1.py +0 -0
  221. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_classify_hook_latency.py +0 -0
  222. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_claude_to_turns.py +0 -0
  223. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_cli_json_flag.py +0 -0
  224. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_cli_ready.py +0 -0
  225. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_cli_review_queue.py +0 -0
  226. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_cli_subcommands.py +0 -0
  227. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_closets.py +0 -0
  228. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_closets_recall_integration.py +0 -0
  229. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_compact_summaries.py +0 -0
  230. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_compaction_trace.py +0 -0
  231. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_config.py +0 -0
  232. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_conflict_resolver.py +0 -0
  233. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_confusion_matrix_eval.py +0 -0
  234. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_connection_retry.py +0 -0
  235. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_connectors.py +0 -0
  236. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_context_hook.py +0 -0
  237. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_context_optimizer.py +0 -0
  238. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_conversation_to_turns.py +0 -0
  239. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_dedup.py +0 -0
  240. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_deterministic_predicates.py +0 -0
  241. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_embeddings_coverage.py +0 -0
  242. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_entity_extractor.py +0 -0
  243. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_entity_extractor_llm.py +0 -0
  244. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_entity_graph.py +0 -0
  245. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_entity_new_kinds.py +0 -0
  246. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_entity_regex_v3.py +0 -0
  247. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_entity_registry.py +0 -0
  248. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_eval_harness.py +0 -0
  249. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_events_schema.py +0 -0
  250. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_extract_llm_ollama.py +0 -0
  251. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_federated_graphify_mcp.py +0 -0
  252. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_feedback.py +0 -0
  253. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_fts5_search.py +0 -0
  254. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_graph_distance.py +0 -0
  255. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_handler_regressions.py +0 -0
  256. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_hook_env_isolation.py +0 -0
  257. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_human_id.py +0 -0
  258. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_incident_drill_runner.py +0 -0
  259. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_integration_workflows.py +0 -0
  260. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_key_rotator.py +0 -0
  261. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_lifecycle.py +0 -0
  262. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_llm_fallback.py +0 -0
  263. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_llm_steward_coverage.py +0 -0
  264. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_llm_steward_key_rotation.py +0 -0
  265. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_mcp_helpers.py +0 -0
  266. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_metrics_exporter.py +0 -0
  267. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_obsidian_mind_patterns.py +0 -0
  268. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_operator.py +0 -0
  269. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_operator_queue.py +0 -0
  270. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_perf_smoke_config.py +0 -0
  271. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_plugins.py +0 -0
  272. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_policy_coverage.py +0 -0
  273. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_policy_mode_env.py +0 -0
  274. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_postgres_parity.py +0 -0
  275. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_qdrant_backend.py +0 -0
  276. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_qmd_bridge.py +0 -0
  277. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_query_classifier.py +0 -0
  278. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_query_expansion.py +0 -0
  279. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_recall_entity_fanout.py +0 -0
  280. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_recall_fusion.py +0 -0
  281. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_recall_latency.py +0 -0
  282. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_recall_precision_at_5.py +0 -0
  283. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_recall_tokenizer.py +0 -0
  284. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_recall_vector_fallback.py +0 -0
  285. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_reliability_hardening.py +0 -0
  286. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_review.py +0 -0
  287. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_rl_trainer.py +0 -0
  288. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_rrf_auto_gate.py +0 -0
  289. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_scheduler.py +0 -0
  290. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_schema.py +0 -0
  291. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_scope_boost.py +0 -0
  292. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_scope_utils.py +0 -0
  293. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_security_access.py +0 -0
  294. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_security_patterns.py +0 -0
  295. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_sensitivity_filter_adversarial.py +0 -0
  296. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_sensitivity_filter_adversarial_v2.py +0 -0
  297. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_service_coverage.py +0 -0
  298. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_session_tracker.py +0 -0
  299. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_snapshot.py +0 -0
  300. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_sqlite_core.py +0 -0
  301. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_staleness.py +0 -0
  302. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_stealth_mode.py +0 -0
  303. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_steward.py +0 -0
  304. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_steward_features.py +0 -0
  305. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_steward_resolution_parity.py +0 -0
  306. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_store_factory.py +0 -0
  307. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_tenant_isolation.py +0 -0
  308. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_turn_schema.py +0 -0
  309. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_two_pass_recall.py +0 -0
  310. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_v311_fixes.py +0 -0
  311. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_v390_e2e.py +0 -0
  312. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_v391_strict_warnings.py +0 -0
  313. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_vault_exporter.py +0 -0
  314. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_vector_search.py +0 -0
  315. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_verbatim_recall.py +0 -0
  316. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_webhook.py +0 -0
  317. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_wiki_binding.py +0 -0
  318. {memorymaster-3.12.0 → memorymaster-3.13.0}/tests/test_wiki_freshness.py +0 -0
  319. {memorymaster-3.12.0 → memorymaster-3.13.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.12.0
3
+ Version: 3.13.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
@@ -50,9 +50,9 @@ Lifecycle-managed claims with citations, conflict detection, steward governance,
50
50
 
51
51
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
52
52
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
53
- [![Tests](https://img.shields.io/badge/tests-1029-green.svg)]()
54
- [![MCP Tools](https://img.shields.io/badge/MCP%20tools-22-purple.svg)]()
55
- [![CLI Commands](https://img.shields.io/badge/CLI%20commands-64-orange.svg)]()
53
+ [![Tests](https://img.shields.io/badge/tests-1953-green.svg)]()
54
+ [![MCP Tools](https://img.shields.io/badge/MCP%20tools-24-purple.svg)]()
55
+ [![CLI Commands](https://img.shields.io/badge/CLI%20commands-86-orange.svg)]()
56
56
  [![PyPI](https://img.shields.io/pypi/v/memorymaster.svg)](https://pypi.org/project/memorymaster/)
57
57
 
58
58
  MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptions, and unsafe disclosure**. It gives Claude Code, Codex, and any MCP-compatible agent persistent, verifiable memory with a full claim lifecycle, citation tracking, conflict detection, and human-in-the-loop governance.
@@ -66,7 +66,7 @@ MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptio
66
66
  │ Agent Runtime │
67
67
  │ (Claude Code / Codex / any MCP-compatible agent) │
68
68
  └────────────┬────────────────────────────────┬───────────────────┘
69
- │ MCP (22 tools) │ CLI (64 commands)
69
+ │ MCP (24 tools) │ CLI (86 commands)
70
70
  v v
71
71
  ┌─────────────────────────────────────────────────────────────────┐
72
72
  │ MemoryMaster Core │
@@ -94,7 +94,8 @@ MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptio
94
94
  - **Steward governance**: multi-probe validators (filesystem, format, citation, semantic, tool) with proposal review
95
95
  - **Conflict resolution**: 5-tier auto (confidence > freshness > citations > LLM > manual)
96
96
  - **Auto-redaction** at ingest: JWT, GitHub tokens, Bearer, AWS keys, SSH keys, custom patterns
97
- - **LLM Wiki**: compiled-truth + append-only timeline articles with progressive-disclosure frontmatter
97
+ - **LLM Wiki**: compiled-truth + append-only timeline articles with progressive-disclosure frontmatter, `explored: true|false` operator-review marker, and inline `> [!contradiction]` Obsidian callouts
98
+ - **Atlas Inbox V1** (new in v3.13.0): WhatsApp ingestion → source/evidence/action proposal lifecycle → Super-Productivity export. Versioned API/CLI contract for downstream consumers (LifeAgent, etc.) — see [`docs/atlas-api-contract-v1.md`](docs/atlas-api-contract-v1.md). Real provider adapters (`OpenAIWhisperTranscriptionProvider`, `TesseractOcrProvider`) behind `Protocol`s; mock providers stay default.
98
99
  - **Dual backend**: SQLite (zero-config) and Postgres (full feature parity with pgvector)
99
100
  - **Dream Bridge** for bidirectional sync with Claude Code's Auto Dream
100
101
  - **7-hook stack**: recall, classify, validate-wiki, session-start, auto-ingest, precompact, steward-cron
@@ -6,9 +6,9 @@ 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-1029-green.svg)]()
10
- [![MCP Tools](https://img.shields.io/badge/MCP%20tools-22-purple.svg)]()
11
- [![CLI Commands](https://img.shields.io/badge/CLI%20commands-64-orange.svg)]()
9
+ [![Tests](https://img.shields.io/badge/tests-1953-green.svg)]()
10
+ [![MCP Tools](https://img.shields.io/badge/MCP%20tools-24-purple.svg)]()
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/)
13
13
 
14
14
  MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptions, and unsafe disclosure**. It gives Claude Code, Codex, and any MCP-compatible agent persistent, verifiable memory with a full claim lifecycle, citation tracking, conflict detection, and human-in-the-loop governance.
@@ -22,7 +22,7 @@ MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptio
22
22
  │ Agent Runtime │
23
23
  │ (Claude Code / Codex / any MCP-compatible agent) │
24
24
  └────────────┬────────────────────────────────┬───────────────────┘
25
- │ MCP (22 tools) │ CLI (64 commands)
25
+ │ MCP (24 tools) │ CLI (86 commands)
26
26
  v v
27
27
  ┌─────────────────────────────────────────────────────────────────┐
28
28
  │ MemoryMaster Core │
@@ -50,7 +50,8 @@ MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptio
50
50
  - **Steward governance**: multi-probe validators (filesystem, format, citation, semantic, tool) with proposal review
51
51
  - **Conflict resolution**: 5-tier auto (confidence > freshness > citations > LLM > manual)
52
52
  - **Auto-redaction** at ingest: JWT, GitHub tokens, Bearer, AWS keys, SSH keys, custom patterns
53
- - **LLM Wiki**: compiled-truth + append-only timeline articles with progressive-disclosure frontmatter
53
+ - **LLM Wiki**: compiled-truth + append-only timeline articles with progressive-disclosure frontmatter, `explored: true|false` operator-review marker, and inline `> [!contradiction]` Obsidian callouts
54
+ - **Atlas Inbox V1** (new in v3.13.0): WhatsApp ingestion → source/evidence/action proposal lifecycle → Super-Productivity export. Versioned API/CLI contract for downstream consumers (LifeAgent, etc.) — see [`docs/atlas-api-contract-v1.md`](docs/atlas-api-contract-v1.md). Real provider adapters (`OpenAIWhisperTranscriptionProvider`, `TesseractOcrProvider`) behind `Protocol`s; mock providers stay default.
54
55
  - **Dual backend**: SQLite (zero-config) and Postgres (full feature parity with pgvector)
55
56
  - **Dream Bridge** for bidirectional sync with Claude Code's Auto Dream
56
57
  - **7-hook stack**: recall, classify, validate-wiki, session-start, auto-ingest, precompact, steward-cron
@@ -52,6 +52,151 @@ class _SchemaMixin:
52
52
  "CREATE INDEX IF NOT EXISTS idx_embeddings_updated_at ON claim_embeddings(updated_at)"
53
53
  )
54
54
 
55
+ @staticmethod
56
+ def _ensure_atlas_source_schema(conn: sqlite3.Connection) -> None:
57
+ """Ensure Atlas Inbox external source/evidence/action proposal tables exist.
58
+
59
+ Critical ordering (forward-migration aware):
60
+ 1. CREATE TABLE IF NOT EXISTS — idempotent on existing tables
61
+ but does NOT add new columns to pre-existing tables.
62
+ 2. ALTER TABLE ADD COLUMN — forward-migrate columns added in
63
+ later versions (idempotent via duplicate-column catch).
64
+ 3. CREATE INDEX IF NOT EXISTS — runs LAST, after columns are
65
+ guaranteed to exist on both fresh and stale DBs.
66
+
67
+ Bug history: in v1.5.0, the index-on-new-column statements were
68
+ in the same executescript as CREATE TABLE, which fired BEFORE
69
+ the ALTER. On a stale Atlas DB (pre-sensitivity), CREATE INDEX
70
+ ON source_items(sensitivity) failed with 'no such column'. v1.5.1
71
+ splits the script and runs ALTER between the table and index
72
+ phases. See PR #27 / claim mm-ce8b.
73
+ """
74
+ # Phase 1: tables (idempotent — IF NOT EXISTS)
75
+ conn.executescript(
76
+ """
77
+ CREATE TABLE IF NOT EXISTS external_sources (
78
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
79
+ source_type TEXT NOT NULL,
80
+ display_name TEXT NOT NULL,
81
+ config_json TEXT,
82
+ created_at TEXT NOT NULL,
83
+ updated_at TEXT NOT NULL,
84
+ UNIQUE (source_type, display_name)
85
+ );
86
+
87
+ CREATE TABLE IF NOT EXISTS source_items (
88
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
89
+ source_id INTEGER NOT NULL,
90
+ source_item_id TEXT NOT NULL,
91
+ item_type TEXT NOT NULL,
92
+ chat_id TEXT,
93
+ sender_id TEXT,
94
+ sender_name TEXT,
95
+ occurred_at TEXT,
96
+ text TEXT,
97
+ payload_json TEXT,
98
+ content_hash TEXT,
99
+ sensitivity TEXT CHECK (sensitivity IS NULL OR sensitivity IN ('none','low','medium','high','redacted')),
100
+ created_at TEXT NOT NULL,
101
+ updated_at TEXT NOT NULL,
102
+ FOREIGN KEY (source_id) REFERENCES external_sources(id) ON DELETE CASCADE,
103
+ UNIQUE (source_id, source_item_id)
104
+ );
105
+
106
+ CREATE TABLE IF NOT EXISTS evidence_items (
107
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
108
+ source_item_id INTEGER NOT NULL,
109
+ evidence_type TEXT NOT NULL,
110
+ text TEXT,
111
+ media_path TEXT,
112
+ provider TEXT,
113
+ confidence REAL CHECK (confidence IS NULL OR (confidence >= 0.0 AND confidence <= 1.0)),
114
+ payload_json TEXT,
115
+ sensitivity TEXT CHECK (sensitivity IS NULL OR sensitivity IN ('none','low','medium','high','redacted')),
116
+ created_at TEXT NOT NULL,
117
+ FOREIGN KEY (source_item_id) REFERENCES source_items(id) ON DELETE CASCADE
118
+ );
119
+
120
+ CREATE TABLE IF NOT EXISTS action_proposals (
121
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
122
+ proposal_type TEXT NOT NULL,
123
+ title TEXT NOT NULL,
124
+ description TEXT,
125
+ source_item_id INTEGER,
126
+ evidence_item_id INTEGER,
127
+ claim_id INTEGER,
128
+ suggested_due_at TEXT,
129
+ destination TEXT NOT NULL DEFAULT 'manual',
130
+ status TEXT NOT NULL DEFAULT 'candidate'
131
+ CHECK (status IN ('candidate', 'approved', 'rejected', 'exported', 'failed')),
132
+ confidence REAL NOT NULL DEFAULT 0.5 CHECK (confidence >= 0.0 AND confidence <= 1.0),
133
+ payload_json TEXT,
134
+ exported_at TEXT,
135
+ external_ref TEXT,
136
+ idempotency_key TEXT,
137
+ created_at TEXT NOT NULL,
138
+ updated_at TEXT NOT NULL,
139
+ FOREIGN KEY (source_item_id) REFERENCES source_items(id) ON DELETE SET NULL,
140
+ FOREIGN KEY (evidence_item_id) REFERENCES evidence_items(id) ON DELETE SET NULL,
141
+ FOREIGN KEY (claim_id) REFERENCES claims(id) ON DELETE SET NULL
142
+ );
143
+
144
+ CREATE TABLE IF NOT EXISTS media_retry_queue (
145
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
146
+ source_item_id INTEGER NOT NULL,
147
+ media_key TEXT NOT NULL,
148
+ chat_id TEXT,
149
+ media_type TEXT,
150
+ media_path TEXT,
151
+ media_url TEXT,
152
+ status TEXT NOT NULL DEFAULT 'pending'
153
+ CHECK (status IN ('pending', 'retrying', 'expired', 'done', 'failed')),
154
+ attempt_count INTEGER NOT NULL DEFAULT 0,
155
+ last_http_status INTEGER,
156
+ last_error TEXT,
157
+ next_attempt_time TEXT,
158
+ created_at TEXT NOT NULL,
159
+ updated_at TEXT NOT NULL,
160
+ FOREIGN KEY (source_item_id) REFERENCES source_items(id) ON DELETE CASCADE,
161
+ UNIQUE (source_item_id, media_key)
162
+ );
163
+ """
164
+ )
165
+
166
+ # Phase 2: forward-migrate columns added in later versions.
167
+ # Pattern matches _ensure_claim_idempotency_schema. MUST run BEFORE
168
+ # any indexes that reference these columns (otherwise stale DBs
169
+ # fail with 'no such column').
170
+ for table in ("source_items", "evidence_items"):
171
+ try:
172
+ conn.execute(f"ALTER TABLE {table} ADD COLUMN sensitivity TEXT")
173
+ except sqlite3.OperationalError as exc:
174
+ if "duplicate column name" not in str(exc).lower():
175
+ raise
176
+
177
+ # Phase 3: indexes (now safe — all columns guaranteed to exist).
178
+ conn.executescript(
179
+ """
180
+ CREATE INDEX IF NOT EXISTS idx_external_sources_type ON external_sources(source_type);
181
+ CREATE INDEX IF NOT EXISTS idx_source_items_source_id ON source_items(source_id);
182
+ CREATE INDEX IF NOT EXISTS idx_source_items_chat_id ON source_items(chat_id);
183
+ CREATE INDEX IF NOT EXISTS idx_source_items_occurred_at ON source_items(occurred_at);
184
+ CREATE INDEX IF NOT EXISTS idx_source_items_content_hash ON source_items(content_hash);
185
+ CREATE INDEX IF NOT EXISTS idx_evidence_items_source_item_id ON evidence_items(source_item_id);
186
+ CREATE INDEX IF NOT EXISTS idx_evidence_items_type ON evidence_items(evidence_type);
187
+ CREATE INDEX IF NOT EXISTS idx_action_proposals_status ON action_proposals(status);
188
+ CREATE INDEX IF NOT EXISTS idx_action_proposals_destination ON action_proposals(destination);
189
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_action_proposals_idempotency_key
190
+ ON action_proposals(idempotency_key)
191
+ WHERE idempotency_key IS NOT NULL;
192
+ CREATE INDEX IF NOT EXISTS idx_source_items_sensitivity ON source_items(sensitivity);
193
+ CREATE INDEX IF NOT EXISTS idx_evidence_items_sensitivity ON evidence_items(sensitivity);
194
+ CREATE INDEX IF NOT EXISTS idx_media_retry_status ON media_retry_queue(status);
195
+ CREATE INDEX IF NOT EXISTS idx_media_retry_next_attempt ON media_retry_queue(next_attempt_time);
196
+ CREATE INDEX IF NOT EXISTS idx_media_retry_source_item ON media_retry_queue(source_item_id);
197
+ """
198
+ )
199
+
55
200
 
56
201
  @staticmethod
57
202
  def _ensure_claim_idempotency_schema(conn: sqlite3.Connection) -> None: