memorymaster 3.12.0__tar.gz → 3.14.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.
- {memorymaster-3.12.0/memorymaster.egg-info → memorymaster-3.14.0}/PKG-INFO +29 -32
- {memorymaster-3.12.0 → memorymaster-3.14.0}/README.md +28 -31
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/_storage_lifecycle.py +60 -10
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/_storage_schema.py +145 -0
- memorymaster-3.14.0/memorymaster/_storage_sources.py +979 -0
- memorymaster-3.14.0/memorymaster/action_exporters.py +91 -0
- memorymaster-3.14.0/memorymaster/action_extractor.py +212 -0
- memorymaster-3.14.0/memorymaster/atlas_claim_extractor.py +162 -0
- memorymaster-3.14.0/memorymaster/atlas_contract.py +381 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/auto_resolver.py +51 -45
- memorymaster-3.14.0/memorymaster/candidate_dedupe.py +288 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/claim_verifier.py +0 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/cli.py +137 -4
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/cli_handlers_basic.py +624 -4
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/cli_handlers_curation.py +32 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/cli_helpers.py +15 -2
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config.py +76 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/hooks/memorymaster-auto-ingest.py +23 -6
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/hooks/memorymaster-dream-sync.py +2 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/hooks/memorymaster-precompact.py +30 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/hooks/memorymaster-recall.py +3 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/hooks/memorymaster-steward-cycle.py +9 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/hooks/memorymaster-validate-wiki.py +1 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/conflict_resolver.py +113 -2
- memorymaster-3.14.0/memorymaster/connectors/__init__.py +2 -0
- memorymaster-3.14.0/memorymaster/connectors/whatsapp.py +235 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/context_hook.py +137 -2
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/context_optimizer.py +161 -19
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/dashboard.py +433 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/db_merge.py +133 -11
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/dream_bridge.py +12 -5
- memorymaster-3.14.0/memorymaster/jobs/calibration.py +120 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/jobs/compact_summaries.py +6 -2
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/jobs/compactor.py +102 -13
- memorymaster-3.14.0/memorymaster/jobs/decay.py +131 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/jobs/dedup.py +155 -2
- memorymaster-3.14.0/memorymaster/jobs/entity_graph_export.py +210 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/lifecycle.py +31 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/llm_provider.py +86 -2
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/llm_steward.py +99 -7
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/mcp_server.py +511 -34
- memorymaster-3.14.0/memorymaster/mcp_usage.py +43 -0
- memorymaster-3.14.0/memorymaster/media_processing.py +199 -0
- memorymaster-3.14.0/memorymaster/media_providers.py +256 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/models.py +106 -0
- memorymaster-3.14.0/memorymaster/observability.py +183 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/postgres_store.py +912 -0
- memorymaster-3.14.0/memorymaster/schema.sql +239 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/schema_postgres.sql +117 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/security.py +7 -2
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/service.py +549 -7
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/setup_hooks.py +1 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/snapshot.py +64 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/steward.py +16 -14
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/steward_classifier.py +5 -2
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/steward_features.py +4 -5
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/storage.py +3 -28
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/vault_linter.py +164 -13
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/vault_query_capture.py +1 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/verbatim_store.py +57 -12
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/wiki_engine.py +328 -25
- memorymaster-3.14.0/memorymaster/wiki_suggest.py +270 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0/memorymaster.egg-info}/PKG-INFO +29 -32
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster.egg-info/SOURCES.txt +68 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/pyproject.toml +1 -1
- memorymaster-3.14.0/scripts/audit_dedupe_precision.py +121 -0
- memorymaster-3.14.0/scripts/measure_dedupe_thresholds.py +114 -0
- memorymaster-3.14.0/tests/test_action_exporters.py +68 -0
- memorymaster-3.14.0/tests/test_action_extractor.py +77 -0
- memorymaster-3.14.0/tests/test_atlas_claim_extractor.py +61 -0
- memorymaster-3.14.0/tests/test_atlas_contract.py +1010 -0
- memorymaster-3.14.0/tests/test_atlas_source_schema.py +181 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_auto_resolver.py +10 -18
- memorymaster-3.14.0/tests/test_calibration.py +134 -0
- memorymaster-3.14.0/tests/test_calibration_priors_applied.py +20 -0
- memorymaster-3.14.0/tests/test_candidate_dedupe.py +296 -0
- memorymaster-3.14.0/tests/test_cli_dry_run.py +142 -0
- memorymaster-3.14.0/tests/test_compact_summaries_sensitivity.py +69 -0
- memorymaster-3.14.0/tests/test_compactor_artifact_order.py +40 -0
- memorymaster-3.14.0/tests/test_context_optimizer_provider.py +145 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_dashboard.py +142 -2
- memorymaster-3.14.0/tests/test_dashboard_coverage.py +321 -0
- memorymaster-3.14.0/tests/test_dashboard_latency.py +111 -0
- memorymaster-3.14.0/tests/test_dashboard_lineage.py +70 -0
- memorymaster-3.14.0/tests/test_dashboard_review_queue.py +143 -0
- memorymaster-3.14.0/tests/test_db_merge_confidence_conflict.py +71 -0
- memorymaster-3.14.0/tests/test_db_merge_coverage_v2.py +260 -0
- memorymaster-3.14.0/tests/test_decay_coverage.py +212 -0
- memorymaster-3.14.0/tests/test_decay_respects_pinned.py +120 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_dedup.py +9 -0
- memorymaster-3.14.0/tests/test_dedup_cli.py +120 -0
- memorymaster-3.14.0/tests/test_dedup_conflict_disambiguation.py +52 -0
- memorymaster-3.14.0/tests/test_dream_bridge_coverage_v2.py +186 -0
- memorymaster-3.14.0/tests/test_dream_bridge_sensitivity.py +76 -0
- memorymaster-3.14.0/tests/test_entity_graph_export.py +147 -0
- memorymaster-3.14.0/tests/test_federated_query_safety.py +91 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_graph_store.py +1 -0
- memorymaster-3.14.0/tests/test_lifecycle_supersede_invariant.py +87 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_llm_provider_claude_cli.py +1 -1
- memorymaster-3.14.0/tests/test_llm_provider_key_rotation.py +80 -0
- memorymaster-3.14.0/tests/test_mcp_filter_bypass.py +91 -0
- memorymaster-3.14.0/tests/test_mcp_rate_limit.py +101 -0
- memorymaster-3.14.0/tests/test_mcp_server_validation.py +49 -0
- memorymaster-3.14.0/tests/test_mcp_usage.py +95 -0
- memorymaster-3.14.0/tests/test_media_processing.py +86 -0
- memorymaster-3.14.0/tests/test_meta_decisions.py +125 -0
- memorymaster-3.14.0/tests/test_observability.py +47 -0
- memorymaster-3.14.0/tests/test_resolvers_concurrent_supersede.py +148 -0
- memorymaster-3.14.0/tests/test_retrieval_profile.py +120 -0
- memorymaster-3.14.0/tests/test_sensitivity_filter_t07.py +63 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_snapshot.py +2 -1
- memorymaster-3.14.0/tests/test_snapshot_roundtrip.py +168 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_sqlite_core.py +9 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_steward_classifier.py +2 -1
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_steward_features_v3.py +3 -2
- memorymaster-3.14.0/tests/test_storage_parity.py +67 -0
- memorymaster-3.14.0/tests/test_v313_e2e.py +265 -0
- memorymaster-3.14.0/tests/test_v313_run_cycle_dedupe.py +176 -0
- memorymaster-3.14.0/tests/test_vault_linter_orphan.py +91 -0
- memorymaster-3.14.0/tests/test_verbatim_dedup.py +144 -0
- memorymaster-3.14.0/tests/test_verbatim_store.py +67 -0
- memorymaster-3.14.0/tests/test_verbatim_store_qdrant.py +120 -0
- memorymaster-3.14.0/tests/test_whatsapp_importer.py +106 -0
- memorymaster-3.14.0/tests/test_wiki_autopromote.py +101 -0
- memorymaster-3.14.0/tests/test_wiki_engine_idempotency.py +170 -0
- memorymaster-3.14.0/tests/test_wiki_explored_and_contradictions.py +229 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_wiki_similarity_multiscope.py +3 -1
- memorymaster-3.14.0/tests/test_wiki_suggest.py +124 -0
- memorymaster-3.12.0/memorymaster/config_templates/hooks/memorymaster-observe.py +0 -39
- memorymaster-3.12.0/memorymaster/jobs/decay.py +0 -50
- memorymaster-3.12.0/memorymaster/schema.sql +0 -123
- {memorymaster-3.12.0 → memorymaster-3.14.0}/LICENSE +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/artifacts/bm25-per-field-eval-harness.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/benchmarks/longmemeval_runner.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/benchmarks/longmemeval_vector_runner.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/benchmarks/perf_smoke.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/__init__.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/__main__.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/_storage_read.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/_storage_shared.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/_storage_write_claims.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/access_control.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/auto_extractor.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/claim_edges.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/closets.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/claude-md-append.md +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/codex-agents-md-append.md +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/hooks/memorymaster-classify.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/config_templates/hooks/memorymaster-session-start.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/daily_notes.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/embeddings.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/entity_extractor.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/entity_graph.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/entity_registry.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/federated_graphify.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/feedback.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/graph_store.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/hook_log.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/jobs/__init__.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/jobs/deterministic.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/jobs/extractor.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/jobs/staleness.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/jobs/validator.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/key_rotator.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/metrics_exporter.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/operator.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/operator_queue.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/plugins.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/policy.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/qdrant_backend.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/qdrant_recall_fallback.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/qmd_bridge.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/query_classifier.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/query_expansion.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/recall_fusion.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/recall_tokenizer.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/retrieval.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/retry.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/review.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/rl_trainer.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/scheduler.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/schema.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/scope_utils.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/session_tracker.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/skill_evolver.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/store_factory.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/transcript_miner.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/turn_schema.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/vault_bases.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/vault_curator.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/vault_exporter.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/vault_log.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/vault_synthesis.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/verbatim_recall.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/webhook.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/wiki_freshness.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/wiki_similarity.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster/wiki_validate.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster.egg-info/dependency_links.txt +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster.egg-info/entry_points.txt +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster.egg-info/requires.txt +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/memorymaster.egg-info/top_level.txt +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/agg_recall_latency.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/alert_operator_metrics.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/autoresearch_daemon.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/backfill_entity_extraction.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/backfill_graph_store.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/backfill_stop_hook_citations.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/backtest_steward_classifier.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/build_steward_training_set.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/check_hook_template_drift.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/claude_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/codex_live_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/compaction_edge_cases.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/compaction_trace_report.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/compaction_trace_validate.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/confusion_matrix_eval.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/conversation_importer.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/conversation_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/e2e_operator.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/email_live_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/eval_bm25_sweep.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/eval_classify_f1.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/eval_memorymaster.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/eval_recall_precision_at_5.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/eval_recall_quality.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/eval_steward_pareto.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/eval_verbatim_recall.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/expand_recall_eval.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/generate_drill_signoff.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/git_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/github_live_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/gitnexus_to_claims.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/grid_recall_weights.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/index_claims_to_qdrant.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/ingest_planning_docs.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/jira_live_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/label_prompts_with_judge.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/llm_benchmark.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/merge_scope_variants.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/messages_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/operator_metrics.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/precompute_candidates.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/recurring_incident_drill.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/release_readiness.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/run_codex_autologger.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/run_incident_drill.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/run_longmemeval.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/scheduled_ingest.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/setup-hooks.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/slack_live_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/sync_hook_templates.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/tickets_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/train_steward_classifier.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/scripts/webhook_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/setup.cfg +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/conftest.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/integration/test_extract_llm_ollama_live.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_access_control.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_auto_extractor.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_auto_ingest_hook_citations.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_auto_ingest_hook_schema.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_auto_validate.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_bm25_per_field.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_claim_edges.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_claim_links.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_claim_type_ranking.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_classify_hook_f1.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_classify_hook_latency.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_claude_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_cli_json_flag.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_cli_ready.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_cli_review_queue.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_cli_subcommands.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_closets.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_closets_recall_integration.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_compact_summaries.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_compaction_trace.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_config.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_conflict_resolver.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_confusion_matrix_eval.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_connection_retry.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_connectors.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_context_hook.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_context_optimizer.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_conversation_to_turns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_deterministic_predicates.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_embeddings_coverage.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_entity_extractor.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_entity_extractor_llm.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_entity_graph.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_entity_new_kinds.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_entity_regex_v3.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_entity_registry.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_eval_harness.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_events_schema.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_extract_llm_ollama.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_federated_graphify_mcp.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_feedback.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_fts5_search.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_graph_distance.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_handler_regressions.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_hook_env_isolation.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_human_id.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_incident_drill_runner.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_integration_workflows.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_key_rotator.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_lifecycle.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_llm_fallback.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_llm_steward_coverage.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_llm_steward_key_rotation.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_mcp_helpers.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_metrics_exporter.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_obsidian_mind_patterns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_operator.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_operator_queue.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_perf_smoke_config.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_plugins.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_policy_coverage.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_policy_mode_env.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_postgres_parity.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_qdrant_backend.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_qmd_bridge.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_query_classifier.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_query_expansion.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_recall_entity_fanout.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_recall_fusion.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_recall_latency.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_recall_precision_at_5.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_recall_tokenizer.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_recall_vector_fallback.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_reliability_hardening.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_review.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_rl_trainer.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_rrf_auto_gate.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_scheduler.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_schema.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_scope_boost.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_scope_utils.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_security_access.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_security_patterns.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_sensitivity_filter_adversarial.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_sensitivity_filter_adversarial_v2.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_service_coverage.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_session_tracker.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_staleness.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_stealth_mode.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_steward.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_steward_features.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_steward_resolution_parity.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_store_factory.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_tenant_isolation.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_turn_schema.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_two_pass_recall.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_v311_fixes.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_v390_e2e.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_v391_strict_warnings.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_vault_exporter.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_vector_search.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_verbatim_recall.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_webhook.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_wiki_binding.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.0}/tests/test_wiki_freshness.py +0 -0
- {memorymaster-3.12.0 → memorymaster-3.14.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.
|
|
3
|
+
Version: 3.14.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)
|
|
52
52
|
[](https://www.python.org/downloads/)
|
|
53
|
-
[]()
|
|
54
|
+
[]()
|
|
55
|
+
[]()
|
|
56
56
|
[](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.
|
|
@@ -61,29 +61,23 @@ MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptio
|
|
|
61
61
|
|
|
62
62
|
## Architecture
|
|
63
63
|
|
|
64
|
+
MemoryMaster is layered around MCP/CLI entry points, the `MemoryService` facade, SQLite/Postgres
|
|
65
|
+
storage, optional Qdrant vector search, scheduled jobs, and the Obsidian wiki/vault layer. The
|
|
66
|
+
canonical ingest path is:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
MCP/CLI -> sensitivity filter -> MemoryService.ingest -> store write -> FTS5 index
|
|
64
70
|
```
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
v v
|
|
71
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
72
|
-
│ MemoryMaster Core │
|
|
73
|
-
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌───────────────┐ │
|
|
74
|
-
│ │ Ingestor │ │ Extractor │ │ Validator │ │ State Engine │ │
|
|
75
|
-
│ │ (events) │->│ (claims) │->│ (probes) │->│ (6-state FSM) │ │
|
|
76
|
-
│ └──────────┘ └───────────┘ └──────────┘ └───────────────┘ │
|
|
77
|
-
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌───────────────┐ │
|
|
78
|
-
│ │ Retrieval│ │ Compactor │ │ Steward │ │ Dashboard │ │
|
|
79
|
-
│ │ (hybrid) │ │ (archive) │ │ (govern) │ │ (HTML+SSE) │ │
|
|
80
|
-
│ └──────────┘ └───────────┘ └──────────┘ └───────────────┘ │
|
|
81
|
-
└────────┬──────────────┬──────────────┬──────────┬───────────────┘
|
|
82
|
-
v v v v
|
|
83
|
-
SQLite/Postgres Qdrant Ollama/CLI Claude Code
|
|
84
|
-
(vectors) (LLM stack) Auto Dream + Vault
|
|
71
|
+
|
|
72
|
+
The query path is:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
query_memory -> MemoryService.query -> storage reads + optional Qdrant candidates -> ranked context
|
|
85
76
|
```
|
|
86
77
|
|
|
78
|
+
See [docs/architecture.md](docs/architecture.md) for the current module map, data-flow details,
|
|
79
|
+
recent PR status, and sensitivity-filter invariants.
|
|
80
|
+
|
|
87
81
|
## Key features
|
|
88
82
|
|
|
89
83
|
- **6-state lifecycle**: `candidate` → `confirmed` → `stale` → `superseded` → `conflicted` → `archived`
|
|
@@ -94,7 +88,8 @@ MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptio
|
|
|
94
88
|
- **Steward governance**: multi-probe validators (filesystem, format, citation, semantic, tool) with proposal review
|
|
95
89
|
- **Conflict resolution**: 5-tier auto (confidence > freshness > citations > LLM > manual)
|
|
96
90
|
- **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
|
|
91
|
+
- **LLM Wiki**: compiled-truth + append-only timeline articles with progressive-disclosure frontmatter, `explored: true|false` operator-review marker, and inline `> [!contradiction]` Obsidian callouts
|
|
92
|
+
- **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
93
|
- **Dual backend**: SQLite (zero-config) and Postgres (full feature parity with pgvector)
|
|
99
94
|
- **Dream Bridge** for bidirectional sync with Claude Code's Auto Dream
|
|
100
95
|
- **7-hook stack**: recall, classify, validate-wiki, session-start, auto-ingest, precompact, steward-cron
|
|
@@ -103,18 +98,20 @@ Full feature index lives in [`docs/handbook.md`](docs/handbook.md).
|
|
|
103
98
|
|
|
104
99
|
## Prerequisites
|
|
105
100
|
|
|
106
|
-
**Required**
|
|
101
|
+
**Required (the package won't function without these)**
|
|
107
102
|
|
|
108
103
|
- Python **3.10+** with `pip`
|
|
109
104
|
- Claude Code, Codex, or any MCP-compatible agent
|
|
105
|
+
- **An LLM provider** — pick one: Claude Code OAuth (free if you're a subscriber, set `MEMORYMASTER_LLM_PROVIDER=claude_cli`), a free Gemini API key from [aistudio.google.com](https://aistudio.google.com), OpenAI, Anthropic API, or local Ollama. The steward, auto-ingest, and wiki-absorb cycles all need an LLM — without one, claims pile up as `candidate` and never get validated, deduped, or compiled into the wiki.
|
|
106
|
+
|
|
107
|
+
**Strongly recommended (you'll lose ~80% of the value without these)**
|
|
108
|
+
|
|
109
|
+
- **Node.js 18+** for [graphify](https://github.com/wolverin0/graphify) and [GitNexus](https://github.com/wolverin0/gitnexus) — these are the cached intelligence layers that make MemoryMaster cheap to query. Without them, every "what does this codebase do?" question burns tokens cold-exploring files the graph already mapped. The `intelligence-first` workflow in `CLAUDE.md` assumes both are installed.
|
|
110
|
+
- **Obsidian 1.6+** with the [Bases](https://help.obsidian.md/Plugins/Bases) core plugin — the wiki engine writes plain Markdown so any editor works, but Obsidian's backlinks, graph view, and Bases dashboards are how you actually navigate `wiki-absorb` output. Without Obsidian, the wiki is just a folder of files.
|
|
110
111
|
|
|
111
|
-
**Optional**
|
|
112
|
+
**Optional (nice to have)**
|
|
112
113
|
|
|
113
|
-
- **
|
|
114
|
-
- A free Gemini API key from [aistudio.google.com](https://aistudio.google.com) — powers the auto-ingest hook at ~zero cost
|
|
115
|
-
- **Node.js 18+** for graphify and GitNexus
|
|
116
|
-
- **Obsidian 1.6+** with the Bases core plugin (for visual wiki browsing)
|
|
117
|
-
- **Docker** for Qdrant (SQLite FTS5 is the default and works out of the box)
|
|
114
|
+
- **Docker** for Qdrant — vector retrieval. SQLite FTS5 is the default and works out of the box; add Qdrant when you want semantic recall on top of keyword search.
|
|
118
115
|
|
|
119
116
|
## Quick start
|
|
120
117
|
|
|
@@ -6,9 +6,9 @@ Lifecycle-managed claims with citations, conflict detection, steward governance,
|
|
|
6
6
|
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](https://www.python.org/downloads/)
|
|
9
|
-
[]()
|
|
10
|
+
[]()
|
|
11
|
+
[]()
|
|
12
12
|
[](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.
|
|
@@ -17,29 +17,23 @@ MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptio
|
|
|
17
17
|
|
|
18
18
|
## Architecture
|
|
19
19
|
|
|
20
|
+
MemoryMaster is layered around MCP/CLI entry points, the `MemoryService` facade, SQLite/Postgres
|
|
21
|
+
storage, optional Qdrant vector search, scheduled jobs, and the Obsidian wiki/vault layer. The
|
|
22
|
+
canonical ingest path is:
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
MCP/CLI -> sensitivity filter -> MemoryService.ingest -> store write -> FTS5 index
|
|
20
26
|
```
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
v v
|
|
27
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
28
|
-
│ MemoryMaster Core │
|
|
29
|
-
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌───────────────┐ │
|
|
30
|
-
│ │ Ingestor │ │ Extractor │ │ Validator │ │ State Engine │ │
|
|
31
|
-
│ │ (events) │->│ (claims) │->│ (probes) │->│ (6-state FSM) │ │
|
|
32
|
-
│ └──────────┘ └───────────┘ └──────────┘ └───────────────┘ │
|
|
33
|
-
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌───────────────┐ │
|
|
34
|
-
│ │ Retrieval│ │ Compactor │ │ Steward │ │ Dashboard │ │
|
|
35
|
-
│ │ (hybrid) │ │ (archive) │ │ (govern) │ │ (HTML+SSE) │ │
|
|
36
|
-
│ └──────────┘ └───────────┘ └──────────┘ └───────────────┘ │
|
|
37
|
-
└────────┬──────────────┬──────────────┬──────────┬───────────────┘
|
|
38
|
-
v v v v
|
|
39
|
-
SQLite/Postgres Qdrant Ollama/CLI Claude Code
|
|
40
|
-
(vectors) (LLM stack) Auto Dream + Vault
|
|
27
|
+
|
|
28
|
+
The query path is:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
query_memory -> MemoryService.query -> storage reads + optional Qdrant candidates -> ranked context
|
|
41
32
|
```
|
|
42
33
|
|
|
34
|
+
See [docs/architecture.md](docs/architecture.md) for the current module map, data-flow details,
|
|
35
|
+
recent PR status, and sensitivity-filter invariants.
|
|
36
|
+
|
|
43
37
|
## Key features
|
|
44
38
|
|
|
45
39
|
- **6-state lifecycle**: `candidate` → `confirmed` → `stale` → `superseded` → `conflicted` → `archived`
|
|
@@ -50,7 +44,8 @@ MemoryMaster prevents the #1 problem with agent memory: **drift, stale assumptio
|
|
|
50
44
|
- **Steward governance**: multi-probe validators (filesystem, format, citation, semantic, tool) with proposal review
|
|
51
45
|
- **Conflict resolution**: 5-tier auto (confidence > freshness > citations > LLM > manual)
|
|
52
46
|
- **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
|
|
47
|
+
- **LLM Wiki**: compiled-truth + append-only timeline articles with progressive-disclosure frontmatter, `explored: true|false` operator-review marker, and inline `> [!contradiction]` Obsidian callouts
|
|
48
|
+
- **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
49
|
- **Dual backend**: SQLite (zero-config) and Postgres (full feature parity with pgvector)
|
|
55
50
|
- **Dream Bridge** for bidirectional sync with Claude Code's Auto Dream
|
|
56
51
|
- **7-hook stack**: recall, classify, validate-wiki, session-start, auto-ingest, precompact, steward-cron
|
|
@@ -59,18 +54,20 @@ Full feature index lives in [`docs/handbook.md`](docs/handbook.md).
|
|
|
59
54
|
|
|
60
55
|
## Prerequisites
|
|
61
56
|
|
|
62
|
-
**Required**
|
|
57
|
+
**Required (the package won't function without these)**
|
|
63
58
|
|
|
64
59
|
- Python **3.10+** with `pip`
|
|
65
60
|
- Claude Code, Codex, or any MCP-compatible agent
|
|
61
|
+
- **An LLM provider** — pick one: Claude Code OAuth (free if you're a subscriber, set `MEMORYMASTER_LLM_PROVIDER=claude_cli`), a free Gemini API key from [aistudio.google.com](https://aistudio.google.com), OpenAI, Anthropic API, or local Ollama. The steward, auto-ingest, and wiki-absorb cycles all need an LLM — without one, claims pile up as `candidate` and never get validated, deduped, or compiled into the wiki.
|
|
62
|
+
|
|
63
|
+
**Strongly recommended (you'll lose ~80% of the value without these)**
|
|
64
|
+
|
|
65
|
+
- **Node.js 18+** for [graphify](https://github.com/wolverin0/graphify) and [GitNexus](https://github.com/wolverin0/gitnexus) — these are the cached intelligence layers that make MemoryMaster cheap to query. Without them, every "what does this codebase do?" question burns tokens cold-exploring files the graph already mapped. The `intelligence-first` workflow in `CLAUDE.md` assumes both are installed.
|
|
66
|
+
- **Obsidian 1.6+** with the [Bases](https://help.obsidian.md/Plugins/Bases) core plugin — the wiki engine writes plain Markdown so any editor works, but Obsidian's backlinks, graph view, and Bases dashboards are how you actually navigate `wiki-absorb` output. Without Obsidian, the wiki is just a folder of files.
|
|
66
67
|
|
|
67
|
-
**Optional**
|
|
68
|
+
**Optional (nice to have)**
|
|
68
69
|
|
|
69
|
-
- **
|
|
70
|
-
- A free Gemini API key from [aistudio.google.com](https://aistudio.google.com) — powers the auto-ingest hook at ~zero cost
|
|
71
|
-
- **Node.js 18+** for graphify and GitNexus
|
|
72
|
-
- **Obsidian 1.6+** with the Bases core plugin (for visual wiki browsing)
|
|
73
|
-
- **Docker** for Qdrant (SQLite FTS5 is the default and works out of the box)
|
|
70
|
+
- **Docker** for Qdrant — vector retrieval. SQLite FTS5 is the default and works out of the box; add Qdrant when you want semantic recall on top of keyword search.
|
|
74
71
|
|
|
75
72
|
## Quick start
|
|
76
73
|
|
|
@@ -23,14 +23,14 @@ from memorymaster.models import (
|
|
|
23
23
|
validate_transition_event_type,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
-
logger = logging.getLogger(__name__)
|
|
27
|
-
|
|
28
26
|
from memorymaster._storage_shared import (
|
|
29
27
|
EVENT_HASH_ALGO,
|
|
30
28
|
ConcurrentModificationError,
|
|
31
29
|
utc_now,
|
|
32
30
|
)
|
|
33
31
|
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
34
|
|
|
35
35
|
class _LifecycleMixin:
|
|
36
36
|
|
|
@@ -102,14 +102,64 @@ class _LifecycleMixin:
|
|
|
102
102
|
old_claim = self.get_claim(old_claim_id, include_citations=False)
|
|
103
103
|
if old_claim is None:
|
|
104
104
|
return
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
112
|
-
|
|
105
|
+
if old_claim.status == "superseded" or old_claim.replaced_by_claim_id is not None:
|
|
106
|
+
raise ConcurrentModificationError(
|
|
107
|
+
f"Claim {old_claim_id} was already superseded. Reload and retry."
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
now = utc_now()
|
|
111
|
+
with self.connect() as conn:
|
|
112
|
+
target = conn.execute(
|
|
113
|
+
"SELECT supersedes_claim_id FROM claims WHERE id = ?",
|
|
114
|
+
(new_claim_id,),
|
|
115
|
+
).fetchone()
|
|
116
|
+
if target is None:
|
|
117
|
+
raise ValueError(f"Replacement claim {new_claim_id} does not exist.")
|
|
118
|
+
if target["supersedes_claim_id"] not in {None, old_claim_id}:
|
|
119
|
+
raise ConcurrentModificationError(
|
|
120
|
+
f"Claim {new_claim_id} already supersedes another claim. Reload and retry."
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
cur = conn.execute(
|
|
124
|
+
"""
|
|
125
|
+
UPDATE claims
|
|
126
|
+
SET status = 'superseded', updated_at = ?, replaced_by_claim_id = ?,
|
|
127
|
+
version = version + 1, valid_until = COALESCE(?, valid_until)
|
|
128
|
+
WHERE id = ? AND version = ? AND status != 'superseded'
|
|
129
|
+
AND replaced_by_claim_id IS NULL
|
|
130
|
+
""",
|
|
131
|
+
(now, new_claim_id, now, old_claim_id, old_claim.version),
|
|
132
|
+
)
|
|
133
|
+
if cur.rowcount == 0:
|
|
134
|
+
raise ConcurrentModificationError(
|
|
135
|
+
f"Claim {old_claim_id} was modified by another writer. Reload and retry."
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
cur = conn.execute(
|
|
139
|
+
"""
|
|
140
|
+
UPDATE claims
|
|
141
|
+
SET supersedes_claim_id = ?, updated_at = ?
|
|
142
|
+
WHERE id = ? AND (supersedes_claim_id IS NULL OR supersedes_claim_id = ?)
|
|
143
|
+
""",
|
|
144
|
+
(old_claim_id, now, new_claim_id, old_claim_id),
|
|
145
|
+
)
|
|
146
|
+
if cur.rowcount == 0:
|
|
147
|
+
conn.rollback()
|
|
148
|
+
raise ConcurrentModificationError(
|
|
149
|
+
f"Claim {new_claim_id} was modified by another writer. Reload and retry."
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
self._insert_event_row(
|
|
153
|
+
conn,
|
|
154
|
+
claim_id=old_claim.id,
|
|
155
|
+
event_type="supersession",
|
|
156
|
+
from_status=old_claim.status,
|
|
157
|
+
to_status="superseded",
|
|
158
|
+
details=reason,
|
|
159
|
+
payload_json=json.dumps({"replaced_by_claim_id": new_claim_id}),
|
|
160
|
+
created_at=now,
|
|
161
|
+
)
|
|
162
|
+
conn.commit()
|
|
113
163
|
|
|
114
164
|
|
|
115
165
|
def delete_old_events(self, retain_days: int) -> int:
|
|
@@ -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:
|