memorymaster 3.2.1__tar.gz → 3.3.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.2.1/memorymaster.egg-info → memorymaster-3.3.0}/PKG-INFO +13 -13
- {memorymaster-3.2.1 → memorymaster-3.3.0}/README.md +12 -12
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/__init__.py +1 -1
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/_storage_lifecycle.py +0 -11
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/_storage_read.py +60 -22
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/_storage_schema.py +52 -37
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/_storage_write_claims.py +0 -20
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/cli.py +19 -4
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/cli_handlers_basic.py +2 -8
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/cli_handlers_curation.py +90 -5
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/dream_bridge.py +18 -24
- memorymaster-3.3.0/memorymaster/entity_registry.py +255 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/mcp_server.py +12 -13
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/metrics_exporter.py +1 -1
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/models.py +11 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/security.py +41 -5
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/service.py +27 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/storage.py +7 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/transcript_miner.py +10 -6
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/vault_bases.py +0 -1
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/vault_curator.py +0 -1
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/verbatim_store.py +9 -6
- {memorymaster-3.2.1 → memorymaster-3.3.0/memorymaster.egg-info}/PKG-INFO +13 -13
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster.egg-info/SOURCES.txt +2 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/pyproject.toml +1 -1
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/autoresearch_daemon.py +28 -5
- memorymaster-3.3.0/tests/test_handler_regressions.py +158 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_security_patterns.py +115 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/LICENSE +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/benchmarks/longmemeval_runner.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/benchmarks/longmemeval_vector_runner.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/benchmarks/perf_smoke.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/__main__.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/_storage_shared.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/access_control.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/auto_extractor.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/auto_resolver.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/claim_verifier.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/cli_helpers.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/claude-md-append.md +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/codex-agents-md-append.md +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/hooks/memorymaster-auto-ingest.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/hooks/memorymaster-classify.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/hooks/memorymaster-precompact.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/hooks/memorymaster-recall.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/hooks/memorymaster-session-start.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/hooks/memorymaster-steward-cycle.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/config_templates/hooks/memorymaster-validate-wiki.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/conflict_resolver.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/context_hook.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/context_optimizer.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/daily_notes.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/dashboard.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/db_merge.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/embeddings.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/entity_graph.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/feedback.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/__init__.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/compact_summaries.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/compactor.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/decay.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/dedup.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/deterministic.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/extractor.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/staleness.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/jobs/validator.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/lifecycle.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/llm_provider.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/llm_steward.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/operator.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/operator_queue.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/plugins.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/policy.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/postgres_store.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/qdrant_backend.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/qmd_bridge.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/query_classifier.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/retrieval.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/retry.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/review.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/rl_trainer.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/scheduler.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/schema.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/schema.sql +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/schema_postgres.sql +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/session_tracker.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/setup_hooks.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/skill_evolver.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/snapshot.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/steward.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/store_factory.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/turn_schema.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/vault_exporter.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/vault_linter.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/vault_log.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/vault_query_capture.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/vault_synthesis.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/webhook.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster/wiki_engine.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster.egg-info/dependency_links.txt +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster.egg-info/entry_points.txt +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster.egg-info/requires.txt +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/memorymaster.egg-info/top_level.txt +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/alert_operator_metrics.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/claude_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/codex_live_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/compaction_edge_cases.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/compaction_trace_report.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/compaction_trace_validate.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/confusion_matrix_eval.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/conversation_importer.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/conversation_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/e2e_operator.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/email_live_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/eval_memorymaster.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/generate_drill_signoff.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/git_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/github_live_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/gitnexus_to_claims.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/ingest_planning_docs.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/jira_live_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/messages_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/operator_metrics.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/recurring_incident_drill.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/release_readiness.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/run_codex_autologger.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/run_incident_drill.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/scheduled_ingest.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/setup-hooks.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/slack_live_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/tickets_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/scripts/webhook_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/setup.cfg +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/conftest.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_access_control.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_auto_extractor.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_auto_resolver.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_auto_validate.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_claim_links.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_claude_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_cli_json_flag.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_cli_ready.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_cli_review_queue.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_cli_subcommands.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_compact_summaries.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_compaction_trace.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_config.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_conflict_resolver.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_confusion_matrix_eval.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_connection_retry.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_connectors.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_context_hook.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_context_optimizer.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_conversation_to_turns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_dashboard.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_dedup.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_deterministic_predicates.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_embeddings_coverage.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_entity_graph.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_events_schema.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_feedback.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_fts5_search.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_human_id.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_incident_drill_runner.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_integration_workflows.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_lifecycle.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_llm_steward_coverage.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_llm_steward_key_rotation.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_mcp_helpers.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_metrics_exporter.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_obsidian_mind_patterns.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_operator.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_operator_queue.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_perf_smoke_config.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_plugins.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_policy_coverage.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_postgres_parity.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_qdrant_backend.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_qmd_bridge.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_query_classifier.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_reliability_hardening.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_review.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_rl_trainer.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_scheduler.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_schema.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_security_access.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_service_coverage.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_session_tracker.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_snapshot.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_sqlite_core.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_staleness.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_stealth_mode.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_steward.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_steward_resolution_parity.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_store_factory.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_tenant_isolation.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_turn_schema.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_vault_exporter.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_vector_search.py +0 -0
- {memorymaster-3.2.1 → memorymaster-3.3.0}/tests/test_webhook.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memorymaster
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.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
|
|
@@ -42,9 +42,9 @@ Lifecycle-managed claims with citations, conflict detection, steward governance,
|
|
|
42
42
|
|
|
43
43
|
[](LICENSE)
|
|
44
44
|
[](https://www.python.org/downloads/)
|
|
45
|
-
[]()
|
|
46
|
+
[]()
|
|
47
|
+
[]()
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
@@ -55,9 +55,9 @@ MemoryMaster gives AI coding agents **persistent, verifiable memory** with a ful
|
|
|
55
55
|
| Metric | Count |
|
|
56
56
|
|--------|-------|
|
|
57
57
|
| Source modules | 35+ (20,000+ lines) |
|
|
58
|
-
| Tests |
|
|
59
|
-
| MCP tools |
|
|
60
|
-
| CLI commands |
|
|
58
|
+
| Tests | 1034 across 68 test modules |
|
|
59
|
+
| MCP tools | 22 |
|
|
60
|
+
| CLI commands | 64 |
|
|
61
61
|
| Import connectors | 10+ (Git, Slack, Jira, email, GitHub, conversations) |
|
|
62
62
|
| Utility scripts | 30+ (connectors, benchmarks, drills) |
|
|
63
63
|
|
|
@@ -68,7 +68,7 @@ MemoryMaster gives AI coding agents **persistent, verifiable memory** with a ful
|
|
|
68
68
|
│ Agent Runtime │
|
|
69
69
|
│ (Claude Code / Codex / any MCP-compatible agent) │
|
|
70
70
|
└────────────┬────────────────────────────────┬───────────────────┘
|
|
71
|
-
│ MCP (
|
|
71
|
+
│ MCP (22 tools) │ CLI (64 commands)
|
|
72
72
|
v v
|
|
73
73
|
┌─────────────────────────────────────────────────────────────────┐
|
|
74
74
|
│ MemoryMaster Core │
|
|
@@ -153,7 +153,7 @@ The setup command configures everything interactively:
|
|
|
153
153
|
- **SessionStart hook** — injects recent claims + cycle summary + pending candidates at session start
|
|
154
154
|
- **Auto-ingest hook** — uses a cheap LLM (Gemini Flash Lite/GPT-4o-mini/Haiku/Ollama) to extract learnings from each session, with a block-based checkpoint every 15 human messages
|
|
155
155
|
- **PreCompact hook** — forces save to MemoryMaster before Claude Code compacts context (permanent context loss prevention)
|
|
156
|
-
- **MCP server** —
|
|
156
|
+
- **MCP server** — 22 tools available in all Claude Code & Codex sessions
|
|
157
157
|
- **Steward cron** — validates and curates claims every 6 hours
|
|
158
158
|
- **CLAUDE.md / AGENTS.md** — appends instructions so Claude and Codex actually use MemoryMaster
|
|
159
159
|
- **Obsidian skills** — read/write/search your vault from Claude Code
|
|
@@ -211,7 +211,7 @@ Add to your `.mcp.json` (see [`.mcp.json.example`](.mcp.json.example)):
|
|
|
211
211
|
}
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
-
**
|
|
214
|
+
**22 MCP tools:** `init_db`, `ingest_claim`, `run_cycle`, `run_steward`, `classify_query`, `query_memory`, `query_for_context`, `list_claims`, `redact_claim_payload`, `pin_claim`, `compact_memory`, `list_events`, `search_verbatim`, `open_dashboard`, `list_steward_proposals`, `resolve_steward_proposal`, `extract_entities`, `entity_stats`, `find_related_claims`, `quality_scores`, `recompute_tiers`, `federated_query`
|
|
215
215
|
|
|
216
216
|
## How It All Works (E2E)
|
|
217
217
|
|
|
@@ -257,7 +257,7 @@ YOU SEND A MESSAGE
|
|
|
257
257
|
|-----------|-------------|-----------|
|
|
258
258
|
| **Recall hook** | Injects relevant claims into every prompt | Every message you send |
|
|
259
259
|
| **Auto-ingest hook** | LLM extracts learnings from transcript | Every time Claude stops |
|
|
260
|
-
| **MCP server** (global) |
|
|
260
|
+
| **MCP server** (global) | 22 tools for query/ingest/steward | Always available |
|
|
261
261
|
| **CLAUDE.md append** | Instructions for Claude to use MemoryMaster | Read at session start |
|
|
262
262
|
| **AGENTS.md append** | Instructions for Codex to use MemoryMaster | Read at session start |
|
|
263
263
|
| **Steward cron** | Validates, decays, compacts claims | Every 6 hours |
|
|
@@ -622,7 +622,7 @@ These are optional but enhance the experience:
|
|
|
622
622
|
|
|
623
623
|
| MCP | What it adds | Install |
|
|
624
624
|
|-----|--------------|---------|
|
|
625
|
-
| **memorymaster** | The
|
|
625
|
+
| **memorymaster** | The 22 MCP tools (`ingest_claim`, `query_memory`, `run_cycle`, etc.) | `memorymaster-setup` (interactive; or `python scripts/setup-hooks.py` from clone) |
|
|
626
626
|
| **GitNexus** | Code-graph aware impact analysis before edits | See [GitNexus Integration](#gitnexus-integration-code-intelligence) |
|
|
627
627
|
| **Obsidian CLI** | Vault-aware search via the obsidian CLI tool | `npm install -g obsidian-cli` (requires Obsidian 1.12+) |
|
|
628
628
|
| **Qdrant** | Vector search backend for semantic recall | `docker run -p 6333:6333 qdrant/qdrant` |
|
|
@@ -704,7 +704,7 @@ Key config groups:
|
|
|
704
704
|
# Install with all dev dependencies
|
|
705
705
|
pip install -e ".[dev,mcp,security,embeddings,qdrant]"
|
|
706
706
|
|
|
707
|
-
# Run tests (
|
|
707
|
+
# Run tests (1034 tests)
|
|
708
708
|
pytest tests/ -q
|
|
709
709
|
|
|
710
710
|
# Lint and format
|
|
@@ -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
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -19,9 +19,9 @@ MemoryMaster gives AI coding agents **persistent, verifiable memory** with a ful
|
|
|
19
19
|
| Metric | Count |
|
|
20
20
|
|--------|-------|
|
|
21
21
|
| Source modules | 35+ (20,000+ lines) |
|
|
22
|
-
| Tests |
|
|
23
|
-
| MCP tools |
|
|
24
|
-
| CLI commands |
|
|
22
|
+
| Tests | 1034 across 68 test modules |
|
|
23
|
+
| MCP tools | 22 |
|
|
24
|
+
| CLI commands | 64 |
|
|
25
25
|
| Import connectors | 10+ (Git, Slack, Jira, email, GitHub, conversations) |
|
|
26
26
|
| Utility scripts | 30+ (connectors, benchmarks, drills) |
|
|
27
27
|
|
|
@@ -32,7 +32,7 @@ MemoryMaster gives AI coding agents **persistent, verifiable memory** with a ful
|
|
|
32
32
|
│ Agent Runtime │
|
|
33
33
|
│ (Claude Code / Codex / any MCP-compatible agent) │
|
|
34
34
|
└────────────┬────────────────────────────────┬───────────────────┘
|
|
35
|
-
│ MCP (
|
|
35
|
+
│ MCP (22 tools) │ CLI (64 commands)
|
|
36
36
|
v v
|
|
37
37
|
┌─────────────────────────────────────────────────────────────────┐
|
|
38
38
|
│ MemoryMaster Core │
|
|
@@ -117,7 +117,7 @@ The setup command configures everything interactively:
|
|
|
117
117
|
- **SessionStart hook** — injects recent claims + cycle summary + pending candidates at session start
|
|
118
118
|
- **Auto-ingest hook** — uses a cheap LLM (Gemini Flash Lite/GPT-4o-mini/Haiku/Ollama) to extract learnings from each session, with a block-based checkpoint every 15 human messages
|
|
119
119
|
- **PreCompact hook** — forces save to MemoryMaster before Claude Code compacts context (permanent context loss prevention)
|
|
120
|
-
- **MCP server** —
|
|
120
|
+
- **MCP server** — 22 tools available in all Claude Code & Codex sessions
|
|
121
121
|
- **Steward cron** — validates and curates claims every 6 hours
|
|
122
122
|
- **CLAUDE.md / AGENTS.md** — appends instructions so Claude and Codex actually use MemoryMaster
|
|
123
123
|
- **Obsidian skills** — read/write/search your vault from Claude Code
|
|
@@ -175,7 +175,7 @@ Add to your `.mcp.json` (see [`.mcp.json.example`](.mcp.json.example)):
|
|
|
175
175
|
}
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
**
|
|
178
|
+
**22 MCP tools:** `init_db`, `ingest_claim`, `run_cycle`, `run_steward`, `classify_query`, `query_memory`, `query_for_context`, `list_claims`, `redact_claim_payload`, `pin_claim`, `compact_memory`, `list_events`, `search_verbatim`, `open_dashboard`, `list_steward_proposals`, `resolve_steward_proposal`, `extract_entities`, `entity_stats`, `find_related_claims`, `quality_scores`, `recompute_tiers`, `federated_query`
|
|
179
179
|
|
|
180
180
|
## How It All Works (E2E)
|
|
181
181
|
|
|
@@ -221,7 +221,7 @@ YOU SEND A MESSAGE
|
|
|
221
221
|
|-----------|-------------|-----------|
|
|
222
222
|
| **Recall hook** | Injects relevant claims into every prompt | Every message you send |
|
|
223
223
|
| **Auto-ingest hook** | LLM extracts learnings from transcript | Every time Claude stops |
|
|
224
|
-
| **MCP server** (global) |
|
|
224
|
+
| **MCP server** (global) | 22 tools for query/ingest/steward | Always available |
|
|
225
225
|
| **CLAUDE.md append** | Instructions for Claude to use MemoryMaster | Read at session start |
|
|
226
226
|
| **AGENTS.md append** | Instructions for Codex to use MemoryMaster | Read at session start |
|
|
227
227
|
| **Steward cron** | Validates, decays, compacts claims | Every 6 hours |
|
|
@@ -586,7 +586,7 @@ These are optional but enhance the experience:
|
|
|
586
586
|
|
|
587
587
|
| MCP | What it adds | Install |
|
|
588
588
|
|-----|--------------|---------|
|
|
589
|
-
| **memorymaster** | The
|
|
589
|
+
| **memorymaster** | The 22 MCP tools (`ingest_claim`, `query_memory`, `run_cycle`, etc.) | `memorymaster-setup` (interactive; or `python scripts/setup-hooks.py` from clone) |
|
|
590
590
|
| **GitNexus** | Code-graph aware impact analysis before edits | See [GitNexus Integration](#gitnexus-integration-code-intelligence) |
|
|
591
591
|
| **Obsidian CLI** | Vault-aware search via the obsidian CLI tool | `npm install -g obsidian-cli` (requires Obsidian 1.12+) |
|
|
592
592
|
| **Qdrant** | Vector search backend for semantic recall | `docker run -p 6333:6333 qdrant/qdrant` |
|
|
@@ -668,7 +668,7 @@ Key config groups:
|
|
|
668
668
|
# Install with all dev dependencies
|
|
669
669
|
pip install -e ".[dev,mcp,security,embeddings,qdrant]"
|
|
670
670
|
|
|
671
|
-
# Run tests (
|
|
671
|
+
# Run tests (1034 tests)
|
|
672
672
|
pytest tests/ -q
|
|
673
673
|
|
|
674
674
|
# Lint and format
|
|
@@ -6,24 +6,18 @@ and `self.db_path`. Do not instantiate directly.
|
|
|
6
6
|
"""
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import contextlib
|
|
10
|
-
import hashlib
|
|
11
9
|
import json
|
|
12
10
|
import logging
|
|
13
11
|
import sqlite3
|
|
14
12
|
from datetime import datetime, timedelta, timezone
|
|
15
|
-
from pathlib import Path
|
|
16
13
|
|
|
17
14
|
from memorymaster.embeddings import EmbeddingProvider, cosine_similarity
|
|
18
15
|
from memorymaster.models import (
|
|
19
16
|
CLAIM_LINK_TYPES,
|
|
20
17
|
CLAIM_STATUSES,
|
|
21
18
|
STATUS_TRANSITION_EVENT_TYPES,
|
|
22
|
-
Citation,
|
|
23
|
-
CitationInput,
|
|
24
19
|
Claim,
|
|
25
20
|
ClaimLink,
|
|
26
|
-
Event,
|
|
27
21
|
validate_event_payload,
|
|
28
22
|
validate_event_type,
|
|
29
23
|
validate_transition_event_type,
|
|
@@ -33,12 +27,7 @@ logger = logging.getLogger(__name__)
|
|
|
33
27
|
|
|
34
28
|
from memorymaster._storage_shared import (
|
|
35
29
|
EVENT_HASH_ALGO,
|
|
36
|
-
HUMAN_ID_PREFIX,
|
|
37
|
-
SQLITE_CONFIRMED_TUPLE_GUARD_TRIGGERS,
|
|
38
|
-
SQLITE_EVENTS_APPEND_ONLY_TRIGGERS,
|
|
39
30
|
ConcurrentModificationError,
|
|
40
|
-
generate_human_id_hash,
|
|
41
|
-
generate_top_level_human_id,
|
|
42
31
|
utc_now,
|
|
43
32
|
)
|
|
44
33
|
|
|
@@ -6,41 +6,19 @@ and `self.db_path`. Do not instantiate directly.
|
|
|
6
6
|
"""
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import contextlib
|
|
10
|
-
import hashlib
|
|
11
|
-
import json
|
|
12
9
|
import logging
|
|
13
10
|
import sqlite3
|
|
14
11
|
from datetime import datetime, timedelta, timezone
|
|
15
|
-
from pathlib import Path
|
|
16
12
|
|
|
17
|
-
from memorymaster.embeddings import EmbeddingProvider, cosine_similarity
|
|
18
13
|
from memorymaster.models import (
|
|
19
|
-
CLAIM_LINK_TYPES,
|
|
20
|
-
CLAIM_STATUSES,
|
|
21
|
-
STATUS_TRANSITION_EVENT_TYPES,
|
|
22
14
|
Citation,
|
|
23
|
-
CitationInput,
|
|
24
15
|
Claim,
|
|
25
16
|
ClaimLink,
|
|
26
17
|
Event,
|
|
27
|
-
validate_event_payload,
|
|
28
|
-
validate_event_type,
|
|
29
|
-
validate_transition_event_type,
|
|
30
18
|
)
|
|
31
19
|
|
|
32
20
|
logger = logging.getLogger(__name__)
|
|
33
21
|
|
|
34
|
-
from memorymaster._storage_shared import (
|
|
35
|
-
EVENT_HASH_ALGO,
|
|
36
|
-
HUMAN_ID_PREFIX,
|
|
37
|
-
SQLITE_CONFIRMED_TUPLE_GUARD_TRIGGERS,
|
|
38
|
-
SQLITE_EVENTS_APPEND_ONLY_TRIGGERS,
|
|
39
|
-
ConcurrentModificationError,
|
|
40
|
-
generate_human_id_hash,
|
|
41
|
-
generate_top_level_human_id,
|
|
42
|
-
utc_now,
|
|
43
|
-
)
|
|
44
22
|
|
|
45
23
|
|
|
46
24
|
class _ReadMixin:
|
|
@@ -612,3 +590,63 @@ class _ReadMixin:
|
|
|
612
590
|
).fetchall()
|
|
613
591
|
return [self._row_to_citation(row) for row in rows]
|
|
614
592
|
|
|
593
|
+
def traverse_relationships(
|
|
594
|
+
self,
|
|
595
|
+
start_claim_id: int,
|
|
596
|
+
*,
|
|
597
|
+
link_types: list[str] | None = None,
|
|
598
|
+
max_depth: int = 3,
|
|
599
|
+
direction: str = "both",
|
|
600
|
+
) -> list[dict]:
|
|
601
|
+
"""Traverse the claim relationship graph from a starting claim.
|
|
602
|
+
|
|
603
|
+
Returns a list of dicts: [{"claim": Claim, "depth": int, "path": [int],
|
|
604
|
+
"link_type": str}]. BFS traversal, stops at max_depth. direction can be
|
|
605
|
+
"outgoing" (source→target), "incoming" (target→source), or "both".
|
|
606
|
+
|
|
607
|
+
Inspired by GBrain's graph traversal queries — "what depends on Qdrant?"
|
|
608
|
+
becomes traverse_relationships(qdrant_claim_id, link_types=["depends_on"]).
|
|
609
|
+
"""
|
|
610
|
+
with self.connect() as conn:
|
|
611
|
+
visited: set[int] = {start_claim_id}
|
|
612
|
+
queue: list[tuple[int, int, list[int], str]] = [] # (claim_id, depth, path, via_link_type)
|
|
613
|
+
|
|
614
|
+
# Seed with depth-0 neighbors
|
|
615
|
+
def _get_neighbors(claim_id: int) -> list[tuple[int, str]]:
|
|
616
|
+
neighbors: list[tuple[int, str]] = []
|
|
617
|
+
if direction in ("outgoing", "both"):
|
|
618
|
+
q = "SELECT target_id, link_type FROM claim_links WHERE source_id = ?"
|
|
619
|
+
for row in conn.execute(q, (claim_id,)).fetchall():
|
|
620
|
+
if link_types is None or row[1] in link_types:
|
|
621
|
+
neighbors.append((row[0], row[1]))
|
|
622
|
+
if direction in ("incoming", "both"):
|
|
623
|
+
q = "SELECT source_id, link_type FROM claim_links WHERE target_id = ?"
|
|
624
|
+
for row in conn.execute(q, (claim_id,)).fetchall():
|
|
625
|
+
if link_types is None or row[1] in link_types:
|
|
626
|
+
neighbors.append((row[0], row[1]))
|
|
627
|
+
return neighbors
|
|
628
|
+
|
|
629
|
+
for neighbor_id, link_type in _get_neighbors(start_claim_id):
|
|
630
|
+
if neighbor_id not in visited:
|
|
631
|
+
visited.add(neighbor_id)
|
|
632
|
+
queue.append((neighbor_id, 1, [start_claim_id, neighbor_id], link_type))
|
|
633
|
+
|
|
634
|
+
results: list[dict] = []
|
|
635
|
+
while queue:
|
|
636
|
+
cid, depth, path, via_type = queue.pop(0)
|
|
637
|
+
claim = self.get_claim(cid, include_citations=False)
|
|
638
|
+
if claim:
|
|
639
|
+
results.append({
|
|
640
|
+
"claim": claim,
|
|
641
|
+
"depth": depth,
|
|
642
|
+
"path": path,
|
|
643
|
+
"link_type": via_type,
|
|
644
|
+
})
|
|
645
|
+
if depth < max_depth:
|
|
646
|
+
for neighbor_id, link_type in _get_neighbors(cid):
|
|
647
|
+
if neighbor_id not in visited:
|
|
648
|
+
visited.add(neighbor_id)
|
|
649
|
+
queue.append((neighbor_id, depth + 1, path + [neighbor_id], link_type))
|
|
650
|
+
|
|
651
|
+
return results
|
|
652
|
+
|
|
@@ -6,40 +6,19 @@ and `self.db_path`. Do not instantiate directly.
|
|
|
6
6
|
"""
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import contextlib
|
|
10
9
|
import hashlib
|
|
11
10
|
import json
|
|
12
11
|
import logging
|
|
13
12
|
import sqlite3
|
|
14
|
-
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
|
|
17
|
-
from memorymaster.embeddings import EmbeddingProvider, cosine_similarity
|
|
18
|
-
from memorymaster.models import (
|
|
19
|
-
CLAIM_LINK_TYPES,
|
|
20
|
-
CLAIM_STATUSES,
|
|
21
|
-
STATUS_TRANSITION_EVENT_TYPES,
|
|
22
|
-
Citation,
|
|
23
|
-
CitationInput,
|
|
24
|
-
Claim,
|
|
25
|
-
ClaimLink,
|
|
26
|
-
Event,
|
|
27
|
-
validate_event_payload,
|
|
28
|
-
validate_event_type,
|
|
29
|
-
validate_transition_event_type,
|
|
30
|
-
)
|
|
13
|
+
|
|
31
14
|
|
|
32
15
|
logger = logging.getLogger(__name__)
|
|
33
16
|
|
|
34
17
|
from memorymaster._storage_shared import (
|
|
35
18
|
EVENT_HASH_ALGO,
|
|
36
|
-
HUMAN_ID_PREFIX,
|
|
37
19
|
SQLITE_CONFIRMED_TUPLE_GUARD_TRIGGERS,
|
|
38
20
|
SQLITE_EVENTS_APPEND_ONLY_TRIGGERS,
|
|
39
|
-
ConcurrentModificationError,
|
|
40
|
-
generate_human_id_hash,
|
|
41
21
|
generate_top_level_human_id,
|
|
42
|
-
utc_now,
|
|
43
22
|
)
|
|
44
23
|
|
|
45
24
|
|
|
@@ -283,21 +262,57 @@ class _SchemaMixin:
|
|
|
283
262
|
|
|
284
263
|
@staticmethod
|
|
285
264
|
def _ensure_claim_links_schema(conn: sqlite3.Connection) -> None:
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
265
|
+
from memorymaster.models import CLAIM_LINK_TYPES
|
|
266
|
+
|
|
267
|
+
# Build the CHECK constraint from the canonical CLAIM_LINK_TYPES tuple
|
|
268
|
+
# so new types only need to be added in models.py.
|
|
269
|
+
types_sql = ", ".join(f"'{t}'" for t in CLAIM_LINK_TYPES)
|
|
270
|
+
check_clause = f"CHECK (link_type IN ({types_sql}))"
|
|
271
|
+
|
|
272
|
+
# Check if table exists and whether it needs migration (old CHECK with only 5 types)
|
|
273
|
+
existing = conn.execute(
|
|
274
|
+
"SELECT sql FROM sqlite_master WHERE type='table' AND name='claim_links'"
|
|
275
|
+
).fetchone()
|
|
276
|
+
|
|
277
|
+
if existing and existing[0]:
|
|
278
|
+
# Table exists — check if it has the old 5-type CHECK
|
|
279
|
+
if "'implements'" not in existing[0]:
|
|
280
|
+
# Migrate: rename old → create new → copy → drop old
|
|
281
|
+
conn.execute("ALTER TABLE claim_links RENAME TO _claim_links_old")
|
|
282
|
+
conn.execute(f"""
|
|
283
|
+
CREATE TABLE claim_links (
|
|
284
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
285
|
+
source_id INTEGER NOT NULL,
|
|
286
|
+
target_id INTEGER NOT NULL,
|
|
287
|
+
link_type TEXT NOT NULL,
|
|
288
|
+
created_at TEXT NOT NULL,
|
|
289
|
+
FOREIGN KEY (source_id) REFERENCES claims(id) ON DELETE CASCADE,
|
|
290
|
+
FOREIGN KEY (target_id) REFERENCES claims(id) ON DELETE CASCADE,
|
|
291
|
+
CHECK (source_id <> target_id),
|
|
292
|
+
{check_clause}
|
|
293
|
+
)
|
|
294
|
+
""")
|
|
295
|
+
conn.execute("""
|
|
296
|
+
INSERT INTO claim_links (id, source_id, target_id, link_type, created_at)
|
|
297
|
+
SELECT id, source_id, target_id, link_type, created_at FROM _claim_links_old
|
|
298
|
+
""")
|
|
299
|
+
conn.execute("DROP TABLE _claim_links_old")
|
|
300
|
+
else:
|
|
301
|
+
# Fresh creation
|
|
302
|
+
conn.execute(f"""
|
|
303
|
+
CREATE TABLE IF NOT EXISTS claim_links (
|
|
304
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
305
|
+
source_id INTEGER NOT NULL,
|
|
306
|
+
target_id INTEGER NOT NULL,
|
|
307
|
+
link_type TEXT NOT NULL,
|
|
308
|
+
created_at TEXT NOT NULL,
|
|
309
|
+
FOREIGN KEY (source_id) REFERENCES claims(id) ON DELETE CASCADE,
|
|
310
|
+
FOREIGN KEY (target_id) REFERENCES claims(id) ON DELETE CASCADE,
|
|
311
|
+
CHECK (source_id <> target_id),
|
|
312
|
+
{check_clause}
|
|
313
|
+
)
|
|
314
|
+
""")
|
|
315
|
+
|
|
301
316
|
conn.execute(
|
|
302
317
|
"CREATE UNIQUE INDEX IF NOT EXISTS idx_claim_links_unique ON claim_links(source_id, target_id, link_type)"
|
|
303
318
|
)
|
|
@@ -6,39 +6,19 @@ and `self.db_path`. Do not instantiate directly.
|
|
|
6
6
|
"""
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import contextlib
|
|
10
|
-
import hashlib
|
|
11
9
|
import json
|
|
12
10
|
import logging
|
|
13
11
|
import sqlite3
|
|
14
|
-
from datetime import datetime, timedelta, timezone
|
|
15
|
-
from pathlib import Path
|
|
16
12
|
|
|
17
|
-
from memorymaster.embeddings import EmbeddingProvider, cosine_similarity
|
|
18
13
|
from memorymaster.models import (
|
|
19
|
-
CLAIM_LINK_TYPES,
|
|
20
|
-
CLAIM_STATUSES,
|
|
21
|
-
STATUS_TRANSITION_EVENT_TYPES,
|
|
22
|
-
Citation,
|
|
23
14
|
CitationInput,
|
|
24
15
|
Claim,
|
|
25
|
-
ClaimLink,
|
|
26
|
-
Event,
|
|
27
16
|
validate_event_payload,
|
|
28
|
-
validate_event_type,
|
|
29
|
-
validate_transition_event_type,
|
|
30
17
|
)
|
|
31
18
|
|
|
32
19
|
logger = logging.getLogger(__name__)
|
|
33
20
|
|
|
34
21
|
from memorymaster._storage_shared import (
|
|
35
|
-
EVENT_HASH_ALGO,
|
|
36
|
-
HUMAN_ID_PREFIX,
|
|
37
|
-
SQLITE_CONFIRMED_TUPLE_GUARD_TRIGGERS,
|
|
38
|
-
SQLITE_EVENTS_APPEND_ONLY_TRIGGERS,
|
|
39
|
-
ConcurrentModificationError,
|
|
40
|
-
generate_human_id_hash,
|
|
41
|
-
generate_top_level_human_id,
|
|
42
22
|
utc_now,
|
|
43
23
|
)
|
|
44
24
|
|
|
@@ -3,19 +3,18 @@ from __future__ import annotations
|
|
|
3
3
|
import argparse
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
-
from memorymaster.cli_helpers import (
|
|
6
|
+
from memorymaster.cli_helpers import ( # noqa: F401 — re-export for backward compat with tests/external callers
|
|
7
7
|
STEALTH_DB_NAME,
|
|
8
8
|
_add_cycle_policy_args,
|
|
9
9
|
_json_error,
|
|
10
|
-
_resolve_claim_id,
|
|
10
|
+
_resolve_claim_id,
|
|
11
11
|
_resolve_db_path,
|
|
12
12
|
_stealth_active,
|
|
13
13
|
parse_citation,
|
|
14
14
|
parse_scope_allowlist,
|
|
15
15
|
)
|
|
16
16
|
from memorymaster.context_optimizer import OUTPUT_FORMATS
|
|
17
|
-
from memorymaster.models import CLAIM_LINK_TYPES, CLAIM_STATUSES,
|
|
18
|
-
from memorymaster.policy import POLICY_MODES
|
|
17
|
+
from memorymaster.models import CLAIM_LINK_TYPES, CLAIM_STATUSES, VOLATILITY_LEVELS
|
|
19
18
|
from memorymaster.retrieval import RETRIEVAL_MODES
|
|
20
19
|
from memorymaster.service import MemoryService
|
|
21
20
|
|
|
@@ -376,6 +375,22 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
376
375
|
dream_clean_cmd.add_argument("--project", default=None, help="Project path to compute Claude Code memory dir slug")
|
|
377
376
|
dream_clean_cmd.add_argument("--dry-run", action="store_true", help="Preview what would be removed without deleting files")
|
|
378
377
|
|
|
378
|
+
# Entity registry (GBrain-inspired)
|
|
379
|
+
entity_list = sub.add_parser("entity-list", help="List canonical entities with alias and claim counts")
|
|
380
|
+
entity_list.add_argument("--scope", default="", help="Filter by scope prefix")
|
|
381
|
+
entity_list.add_argument("--type", default="", help="Filter by entity type")
|
|
382
|
+
entity_list.add_argument("--limit", type=int, default=50)
|
|
383
|
+
|
|
384
|
+
entity_merge = sub.add_parser("entity-merge", help="Merge two entities (move aliases + claims to target)")
|
|
385
|
+
entity_merge.add_argument("keep_id", type=int, help="Entity ID to keep")
|
|
386
|
+
entity_merge.add_argument("merge_id", type=int, help="Entity ID to merge into keep_id")
|
|
387
|
+
|
|
388
|
+
entity_aliases_cmd = sub.add_parser("entity-aliases", help="List or add aliases for an entity")
|
|
389
|
+
entity_aliases_cmd.add_argument("entity_id", type=int, help="Entity ID")
|
|
390
|
+
entity_aliases_cmd.add_argument("--add", default="", help="Add this alias to the entity")
|
|
391
|
+
|
|
392
|
+
entity_backfill = sub.add_parser("entity-backfill", help="Backfill entity_id on claims with subject but no entity")
|
|
393
|
+
|
|
379
394
|
return parser
|
|
380
395
|
|
|
381
396
|
|
|
@@ -9,14 +9,13 @@ from __future__ import annotations
|
|
|
9
9
|
import argparse
|
|
10
10
|
import json
|
|
11
11
|
import os
|
|
12
|
-
from dataclasses import asdict
|
|
12
|
+
from dataclasses import asdict
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
import time
|
|
15
15
|
|
|
16
16
|
from memorymaster.cli_helpers import (
|
|
17
17
|
STEALTH_DB_NAME,
|
|
18
18
|
_SCORE_KEYS,
|
|
19
|
-
_add_cycle_policy_args,
|
|
20
19
|
_claim_to_dict,
|
|
21
20
|
_event_to_timeline_entry,
|
|
22
21
|
_json_default,
|
|
@@ -24,19 +23,14 @@ from memorymaster.cli_helpers import (
|
|
|
24
23
|
_json_error,
|
|
25
24
|
_print_claim_brief,
|
|
26
25
|
_resolve_claim_id,
|
|
27
|
-
|
|
26
|
+
_score_str_from_payload,
|
|
28
27
|
_stealth_active,
|
|
29
28
|
parse_citation,
|
|
30
29
|
parse_scope_allowlist,
|
|
31
30
|
print_claim,
|
|
32
31
|
)
|
|
33
|
-
from memorymaster.context_optimizer import OUTPUT_FORMATS
|
|
34
|
-
from memorymaster.models import CLAIM_LINK_TYPES, CLAIM_STATUSES, CitationInput, VOLATILITY_LEVELS
|
|
35
|
-
from memorymaster.policy import POLICY_MODES
|
|
36
|
-
from memorymaster.retrieval import RETRIEVAL_MODES
|
|
37
32
|
from memorymaster.scheduler import run_daemon
|
|
38
33
|
from memorymaster.security import resolve_allow_sensitive_access
|
|
39
|
-
from memorymaster.service import MemoryService
|
|
40
34
|
|
|
41
35
|
|
|
42
36
|
def _handle_create_snapshot(args: argparse.Namespace, db_resolved: Path) -> int:
|