superlocalmemory 2.8.6 → 3.0.0
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.
- package/LICENSE +9 -1
- package/NOTICE +63 -0
- package/README.md +165 -480
- package/bin/slm +17 -449
- package/bin/slm-npm +1 -1
- package/conftest.py +5 -0
- package/docs/api-reference.md +284 -0
- package/docs/architecture.md +149 -0
- package/docs/auto-memory.md +150 -0
- package/docs/cli-reference.md +276 -0
- package/docs/compliance.md +191 -0
- package/docs/configuration.md +182 -0
- package/docs/getting-started.md +102 -0
- package/docs/ide-setup.md +261 -0
- package/docs/mcp-tools.md +220 -0
- package/docs/migration-from-v2.md +170 -0
- package/docs/profiles.md +173 -0
- package/docs/troubleshooting.md +310 -0
- package/{configs → ide/configs}/antigravity-mcp.json +3 -3
- package/ide/configs/chatgpt-desktop-mcp.json +16 -0
- package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
- package/{configs → ide/configs}/codex-mcp.toml +4 -4
- package/{configs → ide/configs}/continue-mcp.yaml +4 -3
- package/{configs → ide/configs}/continue-skills.yaml +6 -6
- package/ide/configs/cursor-mcp.json +15 -0
- package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
- package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
- package/{configs → ide/configs}/opencode-mcp.json +2 -2
- package/{configs → ide/configs}/perplexity-mcp.json +2 -2
- package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
- package/{configs → ide/configs}/windsurf-mcp.json +3 -3
- package/{configs → ide/configs}/zed-mcp.json +2 -2
- package/{hooks → ide/hooks}/context-hook.js +9 -20
- package/ide/hooks/memory-list-skill.js +70 -0
- package/ide/hooks/memory-profile-skill.js +101 -0
- package/ide/hooks/memory-recall-skill.js +62 -0
- package/ide/hooks/memory-remember-skill.js +68 -0
- package/ide/hooks/memory-reset-skill.js +160 -0
- package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
- package/ide/integrations/langchain/README.md +106 -0
- package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
- package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
- package/ide/integrations/langchain/pyproject.toml +38 -0
- package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
- package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
- package/ide/integrations/langchain/tests/test_security.py +117 -0
- package/ide/integrations/llamaindex/README.md +81 -0
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
- package/ide/integrations/llamaindex/pyproject.toml +43 -0
- package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
- package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
- package/ide/integrations/llamaindex/tests/test_security.py +241 -0
- package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
- package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
- package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
- package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
- package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
- package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
- package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
- package/package.json +13 -22
- package/pyproject.toml +85 -0
- package/scripts/build-dmg.sh +417 -0
- package/scripts/install-skills.ps1 +334 -0
- package/scripts/postinstall.js +2 -2
- package/scripts/start-dashboard.ps1 +52 -0
- package/scripts/start-dashboard.sh +41 -0
- package/scripts/sync-wiki.ps1 +127 -0
- package/scripts/sync-wiki.sh +82 -0
- package/scripts/test-dmg.sh +161 -0
- package/scripts/test-npm-package.ps1 +252 -0
- package/scripts/test-npm-package.sh +207 -0
- package/scripts/verify-install.ps1 +294 -0
- package/scripts/verify-install.sh +266 -0
- package/src/superlocalmemory/__init__.py +0 -0
- package/src/superlocalmemory/attribution/__init__.py +9 -0
- package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
- package/src/superlocalmemory/attribution/signer.py +153 -0
- package/src/superlocalmemory/attribution/watermark.py +189 -0
- package/src/superlocalmemory/cli/__init__.py +5 -0
- package/src/superlocalmemory/cli/commands.py +245 -0
- package/src/superlocalmemory/cli/main.py +89 -0
- package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
- package/src/superlocalmemory/cli/post_install.py +99 -0
- package/src/superlocalmemory/cli/setup_wizard.py +129 -0
- package/src/superlocalmemory/compliance/__init__.py +0 -0
- package/src/superlocalmemory/compliance/abac.py +204 -0
- package/src/superlocalmemory/compliance/audit.py +314 -0
- package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
- package/src/superlocalmemory/compliance/gdpr.py +294 -0
- package/src/superlocalmemory/compliance/lifecycle.py +158 -0
- package/src/superlocalmemory/compliance/retention.py +232 -0
- package/src/superlocalmemory/compliance/scheduler.py +148 -0
- package/src/superlocalmemory/core/__init__.py +0 -0
- package/src/superlocalmemory/core/config.py +391 -0
- package/src/superlocalmemory/core/embeddings.py +293 -0
- package/src/superlocalmemory/core/engine.py +701 -0
- package/src/superlocalmemory/core/hooks.py +65 -0
- package/src/superlocalmemory/core/maintenance.py +172 -0
- package/src/superlocalmemory/core/modes.py +140 -0
- package/src/superlocalmemory/core/profiles.py +234 -0
- package/src/superlocalmemory/core/registry.py +117 -0
- package/src/superlocalmemory/dynamics/__init__.py +0 -0
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
- package/src/superlocalmemory/encoding/__init__.py +0 -0
- package/src/superlocalmemory/encoding/consolidator.py +485 -0
- package/src/superlocalmemory/encoding/emotional.py +125 -0
- package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
- package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
- package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
- package/src/superlocalmemory/encoding/foresight.py +91 -0
- package/src/superlocalmemory/encoding/graph_builder.py +302 -0
- package/src/superlocalmemory/encoding/observation_builder.py +160 -0
- package/src/superlocalmemory/encoding/scene_builder.py +183 -0
- package/src/superlocalmemory/encoding/signal_inference.py +90 -0
- package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
- package/src/superlocalmemory/encoding/type_router.py +235 -0
- package/src/superlocalmemory/hooks/__init__.py +3 -0
- package/src/superlocalmemory/hooks/auto_capture.py +111 -0
- package/src/superlocalmemory/hooks/auto_recall.py +93 -0
- package/src/superlocalmemory/hooks/ide_connector.py +204 -0
- package/src/superlocalmemory/hooks/rules_engine.py +99 -0
- package/src/superlocalmemory/infra/__init__.py +3 -0
- package/src/superlocalmemory/infra/auth_middleware.py +82 -0
- package/src/superlocalmemory/infra/backup.py +317 -0
- package/src/superlocalmemory/infra/cache_manager.py +267 -0
- package/src/superlocalmemory/infra/event_bus.py +381 -0
- package/src/superlocalmemory/infra/rate_limiter.py +135 -0
- package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
- package/src/superlocalmemory/learning/__init__.py +0 -0
- package/src/superlocalmemory/learning/adaptive.py +172 -0
- package/src/superlocalmemory/learning/behavioral.py +490 -0
- package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
- package/src/superlocalmemory/learning/bootstrap.py +298 -0
- package/src/superlocalmemory/learning/cross_project.py +399 -0
- package/src/superlocalmemory/learning/database.py +376 -0
- package/src/superlocalmemory/learning/engagement.py +323 -0
- package/src/superlocalmemory/learning/features.py +138 -0
- package/src/superlocalmemory/learning/feedback.py +316 -0
- package/src/superlocalmemory/learning/outcomes.py +255 -0
- package/src/superlocalmemory/learning/project_context.py +366 -0
- package/src/superlocalmemory/learning/ranker.py +155 -0
- package/src/superlocalmemory/learning/source_quality.py +303 -0
- package/src/superlocalmemory/learning/workflows.py +309 -0
- package/src/superlocalmemory/llm/__init__.py +0 -0
- package/src/superlocalmemory/llm/backbone.py +316 -0
- package/src/superlocalmemory/math/__init__.py +0 -0
- package/src/superlocalmemory/math/fisher.py +356 -0
- package/src/superlocalmemory/math/langevin.py +398 -0
- package/src/superlocalmemory/math/sheaf.py +257 -0
- package/src/superlocalmemory/mcp/__init__.py +0 -0
- package/src/superlocalmemory/mcp/resources.py +245 -0
- package/src/superlocalmemory/mcp/server.py +61 -0
- package/src/superlocalmemory/mcp/tools.py +18 -0
- package/src/superlocalmemory/mcp/tools_core.py +305 -0
- package/src/superlocalmemory/mcp/tools_v28.py +223 -0
- package/src/superlocalmemory/mcp/tools_v3.py +286 -0
- package/src/superlocalmemory/retrieval/__init__.py +0 -0
- package/src/superlocalmemory/retrieval/agentic.py +295 -0
- package/src/superlocalmemory/retrieval/ann_index.py +223 -0
- package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
- package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
- package/src/superlocalmemory/retrieval/engine.py +390 -0
- package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
- package/src/superlocalmemory/retrieval/fusion.py +78 -0
- package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
- package/src/superlocalmemory/retrieval/reranker.py +154 -0
- package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
- package/src/superlocalmemory/retrieval/strategy.py +96 -0
- package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
- package/src/superlocalmemory/server/__init__.py +1 -0
- package/src/superlocalmemory/server/api.py +248 -0
- package/src/superlocalmemory/server/routes/__init__.py +4 -0
- package/src/superlocalmemory/server/routes/agents.py +107 -0
- package/src/superlocalmemory/server/routes/backup.py +91 -0
- package/src/superlocalmemory/server/routes/behavioral.py +127 -0
- package/src/superlocalmemory/server/routes/compliance.py +160 -0
- package/src/superlocalmemory/server/routes/data_io.py +188 -0
- package/src/superlocalmemory/server/routes/events.py +183 -0
- package/src/superlocalmemory/server/routes/helpers.py +85 -0
- package/src/superlocalmemory/server/routes/learning.py +273 -0
- package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
- package/src/superlocalmemory/server/routes/memories.py +399 -0
- package/src/superlocalmemory/server/routes/profiles.py +219 -0
- package/src/superlocalmemory/server/routes/stats.py +346 -0
- package/src/superlocalmemory/server/routes/v3_api.py +365 -0
- package/src/superlocalmemory/server/routes/ws.py +82 -0
- package/src/superlocalmemory/server/security_middleware.py +57 -0
- package/src/superlocalmemory/server/ui.py +245 -0
- package/src/superlocalmemory/storage/__init__.py +0 -0
- package/src/superlocalmemory/storage/access_control.py +182 -0
- package/src/superlocalmemory/storage/database.py +594 -0
- package/src/superlocalmemory/storage/migrations.py +303 -0
- package/src/superlocalmemory/storage/models.py +406 -0
- package/src/superlocalmemory/storage/schema.py +726 -0
- package/src/superlocalmemory/storage/v2_migrator.py +317 -0
- package/src/superlocalmemory/trust/__init__.py +0 -0
- package/src/superlocalmemory/trust/gate.py +130 -0
- package/src/superlocalmemory/trust/provenance.py +124 -0
- package/src/superlocalmemory/trust/scorer.py +347 -0
- package/src/superlocalmemory/trust/signals.py +153 -0
- package/ui/index.html +278 -5
- package/ui/js/auto-settings.js +70 -0
- package/ui/js/dashboard.js +90 -0
- package/ui/js/fact-detail.js +92 -0
- package/ui/js/feedback.js +2 -2
- package/ui/js/ide-status.js +102 -0
- package/ui/js/math-health.js +98 -0
- package/ui/js/recall-lab.js +127 -0
- package/ui/js/settings.js +2 -2
- package/ui/js/trust-dashboard.js +73 -0
- package/api_server.py +0 -724
- package/bin/aider-smart +0 -72
- package/bin/superlocalmemoryv2-learning +0 -4
- package/bin/superlocalmemoryv2-list +0 -3
- package/bin/superlocalmemoryv2-patterns +0 -4
- package/bin/superlocalmemoryv2-profile +0 -3
- package/bin/superlocalmemoryv2-recall +0 -3
- package/bin/superlocalmemoryv2-remember +0 -3
- package/bin/superlocalmemoryv2-reset +0 -3
- package/bin/superlocalmemoryv2-status +0 -3
- package/configs/chatgpt-desktop-mcp.json +0 -16
- package/configs/cursor-mcp.json +0 -15
- package/hooks/memory-list-skill.js +0 -139
- package/hooks/memory-profile-skill.js +0 -273
- package/hooks/memory-recall-skill.js +0 -114
- package/hooks/memory-remember-skill.js +0 -127
- package/hooks/memory-reset-skill.js +0 -274
- package/mcp_server.py +0 -1808
- package/requirements-core.txt +0 -22
- package/requirements-learning.txt +0 -12
- package/requirements.txt +0 -12
- package/src/agent_registry.py +0 -411
- package/src/auth_middleware.py +0 -61
- package/src/auto_backup.py +0 -459
- package/src/behavioral/__init__.py +0 -49
- package/src/behavioral/behavioral_listener.py +0 -203
- package/src/behavioral/behavioral_patterns.py +0 -275
- package/src/behavioral/cross_project_transfer.py +0 -206
- package/src/behavioral/outcome_inference.py +0 -194
- package/src/behavioral/outcome_tracker.py +0 -193
- package/src/behavioral/tests/__init__.py +0 -4
- package/src/behavioral/tests/test_behavioral_integration.py +0 -108
- package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
- package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
- package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
- package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
- package/src/behavioral/tests/test_outcome_inference.py +0 -107
- package/src/behavioral/tests/test_outcome_tracker.py +0 -96
- package/src/cache_manager.py +0 -518
- package/src/compliance/__init__.py +0 -48
- package/src/compliance/abac_engine.py +0 -149
- package/src/compliance/abac_middleware.py +0 -116
- package/src/compliance/audit_db.py +0 -215
- package/src/compliance/audit_logger.py +0 -148
- package/src/compliance/retention_manager.py +0 -289
- package/src/compliance/retention_scheduler.py +0 -186
- package/src/compliance/tests/__init__.py +0 -4
- package/src/compliance/tests/test_abac_enforcement.py +0 -95
- package/src/compliance/tests/test_abac_engine.py +0 -124
- package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
- package/src/compliance/tests/test_audit_db.py +0 -123
- package/src/compliance/tests/test_audit_logger.py +0 -98
- package/src/compliance/tests/test_mcp_audit.py +0 -128
- package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
- package/src/compliance/tests/test_retention_manager.py +0 -131
- package/src/compliance/tests/test_retention_scheduler.py +0 -99
- package/src/compression/__init__.py +0 -25
- package/src/compression/cli.py +0 -150
- package/src/compression/cold_storage.py +0 -217
- package/src/compression/config.py +0 -72
- package/src/compression/orchestrator.py +0 -133
- package/src/compression/tier2_compressor.py +0 -228
- package/src/compression/tier3_compressor.py +0 -153
- package/src/compression/tier_classifier.py +0 -148
- package/src/db_connection_manager.py +0 -536
- package/src/embedding_engine.py +0 -63
- package/src/embeddings/__init__.py +0 -47
- package/src/embeddings/cache.py +0 -70
- package/src/embeddings/cli.py +0 -113
- package/src/embeddings/constants.py +0 -47
- package/src/embeddings/database.py +0 -91
- package/src/embeddings/engine.py +0 -247
- package/src/embeddings/model_loader.py +0 -145
- package/src/event_bus.py +0 -562
- package/src/graph/__init__.py +0 -36
- package/src/graph/build_helpers.py +0 -74
- package/src/graph/cli.py +0 -87
- package/src/graph/cluster_builder.py +0 -188
- package/src/graph/cluster_summary.py +0 -148
- package/src/graph/constants.py +0 -47
- package/src/graph/edge_builder.py +0 -162
- package/src/graph/entity_extractor.py +0 -95
- package/src/graph/graph_core.py +0 -226
- package/src/graph/graph_search.py +0 -231
- package/src/graph/hierarchical.py +0 -207
- package/src/graph/schema.py +0 -99
- package/src/graph_engine.py +0 -52
- package/src/hnsw_index.py +0 -628
- package/src/hybrid_search.py +0 -46
- package/src/learning/__init__.py +0 -217
- package/src/learning/adaptive_ranker.py +0 -682
- package/src/learning/bootstrap/__init__.py +0 -69
- package/src/learning/bootstrap/constants.py +0 -93
- package/src/learning/bootstrap/db_queries.py +0 -316
- package/src/learning/bootstrap/sampling.py +0 -82
- package/src/learning/bootstrap/text_utils.py +0 -71
- package/src/learning/cross_project_aggregator.py +0 -857
- package/src/learning/db/__init__.py +0 -40
- package/src/learning/db/constants.py +0 -44
- package/src/learning/db/schema.py +0 -279
- package/src/learning/engagement_tracker.py +0 -628
- package/src/learning/feature_extractor.py +0 -708
- package/src/learning/feedback_collector.py +0 -806
- package/src/learning/learning_db.py +0 -915
- package/src/learning/project_context_manager.py +0 -572
- package/src/learning/ranking/__init__.py +0 -33
- package/src/learning/ranking/constants.py +0 -84
- package/src/learning/ranking/helpers.py +0 -278
- package/src/learning/source_quality_scorer.py +0 -676
- package/src/learning/synthetic_bootstrap.py +0 -755
- package/src/learning/tests/test_adaptive_ranker.py +0 -325
- package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
- package/src/learning/tests/test_aggregator.py +0 -306
- package/src/learning/tests/test_auto_retrain_v28.py +0 -35
- package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
- package/src/learning/tests/test_feature_extractor_v28.py +0 -93
- package/src/learning/tests/test_feedback_collector.py +0 -294
- package/src/learning/tests/test_learning_db.py +0 -602
- package/src/learning/tests/test_learning_db_v28.py +0 -110
- package/src/learning/tests/test_learning_init_v28.py +0 -48
- package/src/learning/tests/test_outcome_signals.py +0 -48
- package/src/learning/tests/test_project_context.py +0 -292
- package/src/learning/tests/test_schema_migration.py +0 -319
- package/src/learning/tests/test_signal_inference.py +0 -397
- package/src/learning/tests/test_source_quality.py +0 -351
- package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
- package/src/learning/tests/test_workflow_miner.py +0 -318
- package/src/learning/workflow_pattern_miner.py +0 -655
- package/src/lifecycle/__init__.py +0 -54
- package/src/lifecycle/bounded_growth.py +0 -239
- package/src/lifecycle/compaction_engine.py +0 -226
- package/src/lifecycle/lifecycle_engine.py +0 -355
- package/src/lifecycle/lifecycle_evaluator.py +0 -257
- package/src/lifecycle/lifecycle_scheduler.py +0 -130
- package/src/lifecycle/retention_policy.py +0 -285
- package/src/lifecycle/tests/test_bounded_growth.py +0 -193
- package/src/lifecycle/tests/test_compaction.py +0 -179
- package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
- package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
- package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
- package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
- package/src/lifecycle/tests/test_mcp_compact.py +0 -149
- package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
- package/src/lifecycle/tests/test_retention_policy.py +0 -162
- package/src/mcp_tools_v28.py +0 -281
- package/src/memory/__init__.py +0 -36
- package/src/memory/cli.py +0 -205
- package/src/memory/constants.py +0 -39
- package/src/memory/helpers.py +0 -28
- package/src/memory/schema.py +0 -166
- package/src/memory-profiles.py +0 -595
- package/src/memory-reset.py +0 -491
- package/src/memory_compression.py +0 -989
- package/src/memory_store_v2.py +0 -1155
- package/src/migrate_v1_to_v2.py +0 -629
- package/src/pattern_learner.py +0 -34
- package/src/patterns/__init__.py +0 -24
- package/src/patterns/analyzers.py +0 -251
- package/src/patterns/learner.py +0 -271
- package/src/patterns/scoring.py +0 -171
- package/src/patterns/store.py +0 -225
- package/src/patterns/terminology.py +0 -140
- package/src/provenance_tracker.py +0 -312
- package/src/qualixar_attribution.py +0 -139
- package/src/qualixar_watermark.py +0 -78
- package/src/query_optimizer.py +0 -511
- package/src/rate_limiter.py +0 -83
- package/src/search/__init__.py +0 -20
- package/src/search/cli.py +0 -77
- package/src/search/constants.py +0 -26
- package/src/search/engine.py +0 -241
- package/src/search/fusion.py +0 -122
- package/src/search/index_loader.py +0 -114
- package/src/search/methods.py +0 -162
- package/src/search_engine_v2.py +0 -401
- package/src/setup_validator.py +0 -482
- package/src/subscription_manager.py +0 -391
- package/src/tree/__init__.py +0 -59
- package/src/tree/builder.py +0 -185
- package/src/tree/nodes.py +0 -202
- package/src/tree/queries.py +0 -257
- package/src/tree/schema.py +0 -80
- package/src/tree_manager.py +0 -19
- package/src/trust/__init__.py +0 -45
- package/src/trust/constants.py +0 -66
- package/src/trust/queries.py +0 -157
- package/src/trust/schema.py +0 -95
- package/src/trust/scorer.py +0 -299
- package/src/trust/signals.py +0 -95
- package/src/trust_scorer.py +0 -44
- package/ui/app.js +0 -1588
- package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
- package/ui/js/graph-cytoscape.js +0 -1168
- package/ui/js/graph-d3-backup.js +0 -32
- package/ui/js/graph.js +0 -32
- package/ui_server.py +0 -286
- /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
- /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
- /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
- /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
- /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
- /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
- /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
- /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
- /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
- /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
- /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
- /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
- /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
- /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
- /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
- /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
- /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
- /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
- /package/{completions → ide/completions}/slm.bash +0 -0
- /package/{completions → ide/completions}/slm.zsh +0 -0
- /package/{configs → ide/configs}/cody-commands.json +0 -0
- /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
- /package/{install.ps1 → scripts/install.ps1} +0 -0
- /package/{install.sh → scripts/install.sh} +0 -0
package/src/trust/queries.py
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""
|
|
5
|
-
Trust query and enforcement mixin for TrustScorer.
|
|
6
|
-
|
|
7
|
-
Contains: get_trust_score, get_beta_params, check_trust, get_signals, get_trust_stats.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
import logging
|
|
12
|
-
from typing import Dict, List
|
|
13
|
-
|
|
14
|
-
from .constants import INITIAL_ALPHA, INITIAL_BETA
|
|
15
|
-
|
|
16
|
-
logger = logging.getLogger("superlocalmemory.trust")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class TrustQueryMixin:
|
|
20
|
-
"""Mixin providing trust query, enforcement, and stats methods."""
|
|
21
|
-
|
|
22
|
-
def get_trust_score(self, agent_id: str) -> float:
|
|
23
|
-
"""
|
|
24
|
-
Get current trust score for an agent.
|
|
25
|
-
|
|
26
|
-
Computes alpha/(alpha+beta) from cached or stored Beta params.
|
|
27
|
-
Returns INITIAL_ALPHA/(INITIAL_ALPHA+INITIAL_BETA) = 0.667 for
|
|
28
|
-
unknown agents.
|
|
29
|
-
"""
|
|
30
|
-
alpha, beta = self._get_beta_params(agent_id)
|
|
31
|
-
if (alpha + beta) > 0:
|
|
32
|
-
return alpha / (alpha + beta)
|
|
33
|
-
return INITIAL_ALPHA / (INITIAL_ALPHA + INITIAL_BETA)
|
|
34
|
-
|
|
35
|
-
def get_beta_params(self, agent_id: str) -> Dict[str, float]:
|
|
36
|
-
"""
|
|
37
|
-
Get the Beta distribution parameters for an agent.
|
|
38
|
-
|
|
39
|
-
Returns:
|
|
40
|
-
{"alpha": float, "beta": float, "trust_score": float}
|
|
41
|
-
"""
|
|
42
|
-
alpha, beta = self._get_beta_params(agent_id)
|
|
43
|
-
score = alpha / (alpha + beta) if (alpha + beta) > 0 else 0.0
|
|
44
|
-
return {
|
|
45
|
-
"alpha": round(alpha, 4),
|
|
46
|
-
"beta": round(beta, 4),
|
|
47
|
-
"trust_score": round(score, 4),
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
def check_trust(self, agent_id: str, operation: str = "write") -> bool:
|
|
51
|
-
"""
|
|
52
|
-
Check if agent is trusted enough for the given operation.
|
|
53
|
-
|
|
54
|
-
v2.6 enforcement: blocks write/delete for agents with trust < 0.3.
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
agent_id: The agent identifier
|
|
58
|
-
operation: One of "read", "write", "delete"
|
|
59
|
-
|
|
60
|
-
Returns:
|
|
61
|
-
True if operation is allowed, False if blocked
|
|
62
|
-
"""
|
|
63
|
-
if operation == "read":
|
|
64
|
-
return True # Reads are always allowed
|
|
65
|
-
|
|
66
|
-
score = self.get_trust_score(agent_id)
|
|
67
|
-
|
|
68
|
-
threshold = 0.3 # Block write/delete below this
|
|
69
|
-
if score < threshold:
|
|
70
|
-
logger.warning(
|
|
71
|
-
"Trust enforcement: agent '%s' blocked from '%s' (trust=%.4f < %.2f)",
|
|
72
|
-
agent_id, operation, score, threshold
|
|
73
|
-
)
|
|
74
|
-
return False
|
|
75
|
-
|
|
76
|
-
return True
|
|
77
|
-
|
|
78
|
-
def get_signals(self, agent_id: str, limit: int = 50) -> List[dict]:
|
|
79
|
-
"""Get recent trust signals for an agent."""
|
|
80
|
-
try:
|
|
81
|
-
from db_connection_manager import DbConnectionManager
|
|
82
|
-
mgr = DbConnectionManager.get_instance(self.db_path)
|
|
83
|
-
|
|
84
|
-
with mgr.read_connection() as conn:
|
|
85
|
-
cursor = conn.cursor()
|
|
86
|
-
cursor.execute("""
|
|
87
|
-
SELECT signal_type, delta, old_score, new_score, context, created_at
|
|
88
|
-
FROM trust_signals
|
|
89
|
-
WHERE agent_id = ?
|
|
90
|
-
ORDER BY created_at DESC
|
|
91
|
-
LIMIT ?
|
|
92
|
-
""", (agent_id, limit))
|
|
93
|
-
|
|
94
|
-
signals = []
|
|
95
|
-
for row in cursor.fetchall():
|
|
96
|
-
ctx = {}
|
|
97
|
-
try:
|
|
98
|
-
ctx = json.loads(row[4]) if row[4] else {}
|
|
99
|
-
except (json.JSONDecodeError, TypeError):
|
|
100
|
-
pass
|
|
101
|
-
signals.append({
|
|
102
|
-
"signal_type": row[0],
|
|
103
|
-
"delta": row[1],
|
|
104
|
-
"old_score": row[2],
|
|
105
|
-
"new_score": row[3],
|
|
106
|
-
"context": ctx,
|
|
107
|
-
"created_at": row[5],
|
|
108
|
-
})
|
|
109
|
-
return signals
|
|
110
|
-
|
|
111
|
-
except Exception as e:
|
|
112
|
-
logger.error("Failed to get trust signals: %s", e)
|
|
113
|
-
return []
|
|
114
|
-
|
|
115
|
-
def get_trust_stats(self) -> dict:
|
|
116
|
-
"""Get trust system statistics."""
|
|
117
|
-
try:
|
|
118
|
-
from db_connection_manager import DbConnectionManager
|
|
119
|
-
mgr = DbConnectionManager.get_instance(self.db_path)
|
|
120
|
-
|
|
121
|
-
with mgr.read_connection() as conn:
|
|
122
|
-
cursor = conn.cursor()
|
|
123
|
-
|
|
124
|
-
cursor.execute("SELECT COUNT(*) FROM trust_signals")
|
|
125
|
-
total_signals = cursor.fetchone()[0]
|
|
126
|
-
|
|
127
|
-
cursor.execute("""
|
|
128
|
-
SELECT signal_type, COUNT(*) FROM trust_signals
|
|
129
|
-
GROUP BY signal_type ORDER BY COUNT(*) DESC
|
|
130
|
-
""")
|
|
131
|
-
by_type = dict(cursor.fetchall())
|
|
132
|
-
|
|
133
|
-
cursor.execute("""
|
|
134
|
-
SELECT agent_id, COUNT(*) FROM trust_signals
|
|
135
|
-
GROUP BY agent_id ORDER BY COUNT(*) DESC LIMIT 10
|
|
136
|
-
""")
|
|
137
|
-
by_agent = dict(cursor.fetchall())
|
|
138
|
-
|
|
139
|
-
cursor.execute("""
|
|
140
|
-
SELECT AVG(trust_score) FROM agent_registry
|
|
141
|
-
WHERE trust_score IS NOT NULL
|
|
142
|
-
""")
|
|
143
|
-
avg = cursor.fetchone()[0]
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
"total_signals": total_signals,
|
|
147
|
-
"by_signal_type": by_type,
|
|
148
|
-
"by_agent": by_agent,
|
|
149
|
-
"avg_trust_score": round(avg, 4) if avg else INITIAL_ALPHA / (INITIAL_ALPHA + INITIAL_BETA),
|
|
150
|
-
"scoring_model": "Beta-Binomial",
|
|
151
|
-
"prior": f"Beta({INITIAL_ALPHA}, {INITIAL_BETA})",
|
|
152
|
-
"enforcement": "enabled (v2.6 -- write/delete blocked below 0.3 trust)",
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
except Exception as e:
|
|
156
|
-
logger.error("Failed to get trust stats: %s", e)
|
|
157
|
-
return {"total_signals": 0, "error": str(e)}
|
package/src/trust/schema.py
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""
|
|
5
|
-
Database schema initialization for the trust scoring system.
|
|
6
|
-
|
|
7
|
-
Creates trust_signals table and adds alpha/beta columns to agent_registry.
|
|
8
|
-
Extracted from TrustScorer._init_schema for modularity.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
from .constants import INITIAL_ALPHA, INITIAL_BETA
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def init_trust_schema(db_path: Path):
|
|
17
|
-
"""
|
|
18
|
-
Create trust_signals table and add alpha/beta columns to agent_registry.
|
|
19
|
-
|
|
20
|
-
Handles both DbConnectionManager (preferred) and direct sqlite3 fallback.
|
|
21
|
-
|
|
22
|
-
Args:
|
|
23
|
-
db_path: Path to the SQLite database file.
|
|
24
|
-
"""
|
|
25
|
-
try:
|
|
26
|
-
from db_connection_manager import DbConnectionManager
|
|
27
|
-
mgr = DbConnectionManager.get_instance(db_path)
|
|
28
|
-
|
|
29
|
-
def _create(conn):
|
|
30
|
-
# Trust signals audit trail
|
|
31
|
-
conn.execute('''
|
|
32
|
-
CREATE TABLE IF NOT EXISTS trust_signals (
|
|
33
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
34
|
-
agent_id TEXT NOT NULL,
|
|
35
|
-
signal_type TEXT NOT NULL,
|
|
36
|
-
delta REAL NOT NULL,
|
|
37
|
-
old_score REAL,
|
|
38
|
-
new_score REAL,
|
|
39
|
-
context TEXT DEFAULT '{}',
|
|
40
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
41
|
-
)
|
|
42
|
-
''')
|
|
43
|
-
conn.execute('''
|
|
44
|
-
CREATE INDEX IF NOT EXISTS idx_trust_agent
|
|
45
|
-
ON trust_signals(agent_id)
|
|
46
|
-
''')
|
|
47
|
-
conn.execute('''
|
|
48
|
-
CREATE INDEX IF NOT EXISTS idx_trust_created
|
|
49
|
-
ON trust_signals(created_at)
|
|
50
|
-
''')
|
|
51
|
-
|
|
52
|
-
# Add trust_alpha and trust_beta columns to agent_registry
|
|
53
|
-
# (backward compatible -- old databases get these columns added)
|
|
54
|
-
for col_name, col_default in [("trust_alpha", INITIAL_ALPHA),
|
|
55
|
-
("trust_beta", INITIAL_BETA)]:
|
|
56
|
-
try:
|
|
57
|
-
conn.execute(
|
|
58
|
-
f'ALTER TABLE agent_registry ADD COLUMN {col_name} REAL DEFAULT {col_default}'
|
|
59
|
-
)
|
|
60
|
-
except Exception:
|
|
61
|
-
pass # Column already exists
|
|
62
|
-
|
|
63
|
-
conn.commit()
|
|
64
|
-
|
|
65
|
-
mgr.execute_write(_create)
|
|
66
|
-
except ImportError:
|
|
67
|
-
import sqlite3
|
|
68
|
-
conn = sqlite3.connect(str(db_path))
|
|
69
|
-
conn.execute('''
|
|
70
|
-
CREATE TABLE IF NOT EXISTS trust_signals (
|
|
71
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
72
|
-
agent_id TEXT NOT NULL,
|
|
73
|
-
signal_type TEXT NOT NULL,
|
|
74
|
-
delta REAL NOT NULL,
|
|
75
|
-
old_score REAL,
|
|
76
|
-
new_score REAL,
|
|
77
|
-
context TEXT DEFAULT '{}',
|
|
78
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
79
|
-
)
|
|
80
|
-
''')
|
|
81
|
-
conn.execute('CREATE INDEX IF NOT EXISTS idx_trust_agent ON trust_signals(agent_id)')
|
|
82
|
-
conn.execute('CREATE INDEX IF NOT EXISTS idx_trust_created ON trust_signals(created_at)')
|
|
83
|
-
|
|
84
|
-
# Add trust_alpha and trust_beta columns (backward compatible)
|
|
85
|
-
for col_name, col_default in [("trust_alpha", INITIAL_ALPHA),
|
|
86
|
-
("trust_beta", INITIAL_BETA)]:
|
|
87
|
-
try:
|
|
88
|
-
conn.execute(
|
|
89
|
-
f'ALTER TABLE agent_registry ADD COLUMN {col_name} REAL DEFAULT {col_default}'
|
|
90
|
-
)
|
|
91
|
-
except sqlite3.OperationalError:
|
|
92
|
-
pass # Column already exists
|
|
93
|
-
|
|
94
|
-
conn.commit()
|
|
95
|
-
conn.close()
|
package/src/trust/scorer.py
DELETED
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""SuperLocalMemory V2 - Trust Scorer (core class)
|
|
5
|
-
. MIT License.
|
|
6
|
-
|
|
7
|
-
Bayesian Beta-Binomial trust scoring for AI agents.
|
|
8
|
-
Core class with Beta parameter management and signal recording.
|
|
9
|
-
Query/stats via TrustQueryMixin; signal helpers via TrustSignalsMixin.
|
|
10
|
-
"""
|
|
11
|
-
import json
|
|
12
|
-
import logging
|
|
13
|
-
import threading
|
|
14
|
-
from pathlib import Path
|
|
15
|
-
from typing import Optional, Dict
|
|
16
|
-
|
|
17
|
-
from .constants import (
|
|
18
|
-
SIGNAL_WEIGHTS,
|
|
19
|
-
INITIAL_ALPHA,
|
|
20
|
-
INITIAL_BETA,
|
|
21
|
-
DECAY_FACTOR,
|
|
22
|
-
DECAY_INTERVAL,
|
|
23
|
-
ALPHA_FLOOR,
|
|
24
|
-
BETA_FLOOR,
|
|
25
|
-
)
|
|
26
|
-
from .schema import init_trust_schema
|
|
27
|
-
from .signals import TrustSignalsMixin
|
|
28
|
-
from .queries import TrustQueryMixin
|
|
29
|
-
|
|
30
|
-
logger = logging.getLogger("superlocalmemory.trust")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class TrustScorer(TrustSignalsMixin, TrustQueryMixin):
|
|
34
|
-
"""
|
|
35
|
-
Bayesian Beta-Binomial trust scorer for AI agents.
|
|
36
|
-
|
|
37
|
-
Each agent is modeled as Beta(alpha, beta). Positive signals
|
|
38
|
-
increment alpha, negative signals increment beta. The trust
|
|
39
|
-
score is the posterior mean: alpha / (alpha + beta).
|
|
40
|
-
|
|
41
|
-
Thread-safe singleton per database path.
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
_instances: Dict[str, "TrustScorer"] = {}
|
|
45
|
-
_instances_lock = threading.Lock()
|
|
46
|
-
|
|
47
|
-
@classmethod
|
|
48
|
-
def get_instance(cls, db_path: Optional[Path] = None) -> "TrustScorer":
|
|
49
|
-
"""Get or create the singleton TrustScorer."""
|
|
50
|
-
if db_path is None:
|
|
51
|
-
db_path = Path.home() / ".claude-memory" / "memory.db"
|
|
52
|
-
key = str(db_path)
|
|
53
|
-
with cls._instances_lock:
|
|
54
|
-
if key not in cls._instances:
|
|
55
|
-
cls._instances[key] = cls(db_path)
|
|
56
|
-
return cls._instances[key]
|
|
57
|
-
|
|
58
|
-
@classmethod
|
|
59
|
-
def reset_instance(cls, db_path: Optional[Path] = None):
|
|
60
|
-
"""Remove singleton. Used for testing."""
|
|
61
|
-
with cls._instances_lock:
|
|
62
|
-
if db_path is None:
|
|
63
|
-
cls._instances.clear()
|
|
64
|
-
else:
|
|
65
|
-
key = str(db_path)
|
|
66
|
-
if key in cls._instances:
|
|
67
|
-
del cls._instances[key]
|
|
68
|
-
|
|
69
|
-
def __init__(self, db_path: Path):
|
|
70
|
-
self.db_path = Path(db_path)
|
|
71
|
-
|
|
72
|
-
# In-memory signal log for burst detection (agent_id -> list of timestamps)
|
|
73
|
-
self._write_timestamps: Dict[str, list] = {}
|
|
74
|
-
self._timestamps_lock = threading.Lock()
|
|
75
|
-
|
|
76
|
-
# Signal count per agent (for decay interval tracking)
|
|
77
|
-
self._signal_counts: Dict[str, int] = {}
|
|
78
|
-
|
|
79
|
-
# In-memory cache of Beta parameters per agent
|
|
80
|
-
# Key: agent_id, Value: (alpha, beta)
|
|
81
|
-
self._beta_params: Dict[str, tuple] = {}
|
|
82
|
-
self._beta_lock = threading.Lock()
|
|
83
|
-
|
|
84
|
-
self._init_schema()
|
|
85
|
-
logger.info("TrustScorer initialized (Beta-Binomial -- alpha=%.1f, beta=%.1f prior)",
|
|
86
|
-
INITIAL_ALPHA, INITIAL_BETA)
|
|
87
|
-
|
|
88
|
-
def _init_schema(self):
|
|
89
|
-
"""Create trust_signals table and add alpha/beta columns to agent_registry."""
|
|
90
|
-
init_trust_schema(self.db_path)
|
|
91
|
-
|
|
92
|
-
# =========================================================================
|
|
93
|
-
# Beta Parameter Management
|
|
94
|
-
# =========================================================================
|
|
95
|
-
|
|
96
|
-
def _get_beta_params(self, agent_id: str) -> tuple:
|
|
97
|
-
"""
|
|
98
|
-
Get (alpha, beta) for an agent. Checks in-memory cache first,
|
|
99
|
-
then database, then falls back to prior defaults.
|
|
100
|
-
|
|
101
|
-
Returns:
|
|
102
|
-
(alpha, beta) tuple
|
|
103
|
-
"""
|
|
104
|
-
with self._beta_lock:
|
|
105
|
-
if agent_id in self._beta_params:
|
|
106
|
-
return self._beta_params[agent_id]
|
|
107
|
-
|
|
108
|
-
# Not in cache -- read from database
|
|
109
|
-
alpha, beta = None, None
|
|
110
|
-
try:
|
|
111
|
-
from db_connection_manager import DbConnectionManager
|
|
112
|
-
mgr = DbConnectionManager.get_instance(self.db_path)
|
|
113
|
-
|
|
114
|
-
with mgr.read_connection() as conn:
|
|
115
|
-
cursor = conn.cursor()
|
|
116
|
-
cursor.execute(
|
|
117
|
-
"SELECT trust_alpha, trust_beta FROM agent_registry WHERE agent_id = ?",
|
|
118
|
-
(agent_id,)
|
|
119
|
-
)
|
|
120
|
-
row = cursor.fetchone()
|
|
121
|
-
if row:
|
|
122
|
-
alpha = row[0]
|
|
123
|
-
beta = row[1]
|
|
124
|
-
except Exception:
|
|
125
|
-
pass
|
|
126
|
-
|
|
127
|
-
# Fall back to defaults if NULL or missing
|
|
128
|
-
if alpha is None or beta is None:
|
|
129
|
-
alpha = INITIAL_ALPHA
|
|
130
|
-
beta = INITIAL_BETA
|
|
131
|
-
|
|
132
|
-
with self._beta_lock:
|
|
133
|
-
self._beta_params[agent_id] = (alpha, beta)
|
|
134
|
-
|
|
135
|
-
return (alpha, beta)
|
|
136
|
-
|
|
137
|
-
def _set_beta_params(self, agent_id: str, alpha: float, beta: float):
|
|
138
|
-
"""
|
|
139
|
-
Update (alpha, beta) in cache and persist to agent_registry.
|
|
140
|
-
Also computes and stores the derived trust_score = alpha/(alpha+beta).
|
|
141
|
-
"""
|
|
142
|
-
trust_score = alpha / (alpha + beta) if (alpha + beta) > 0 else 0.0
|
|
143
|
-
|
|
144
|
-
with self._beta_lock:
|
|
145
|
-
self._beta_params[agent_id] = (alpha, beta)
|
|
146
|
-
|
|
147
|
-
try:
|
|
148
|
-
from db_connection_manager import DbConnectionManager
|
|
149
|
-
mgr = DbConnectionManager.get_instance(self.db_path)
|
|
150
|
-
|
|
151
|
-
def _update(conn):
|
|
152
|
-
conn.execute(
|
|
153
|
-
"""UPDATE agent_registry
|
|
154
|
-
SET trust_score = ?, trust_alpha = ?, trust_beta = ?
|
|
155
|
-
WHERE agent_id = ?""",
|
|
156
|
-
(round(trust_score, 4), round(alpha, 4), round(beta, 4), agent_id)
|
|
157
|
-
)
|
|
158
|
-
conn.commit()
|
|
159
|
-
|
|
160
|
-
mgr.execute_write(_update)
|
|
161
|
-
except Exception as e:
|
|
162
|
-
logger.error("Failed to persist Beta params for %s: %s", agent_id, e)
|
|
163
|
-
|
|
164
|
-
def _apply_decay(self, agent_id: str, alpha: float, beta: float) -> tuple:
|
|
165
|
-
"""
|
|
166
|
-
Apply periodic decay to alpha and beta to forget very old signals.
|
|
167
|
-
|
|
168
|
-
Called every DECAY_INTERVAL signals per agent.
|
|
169
|
-
Multiplies both by DECAY_FACTOR with floor constraints.
|
|
170
|
-
|
|
171
|
-
Returns:
|
|
172
|
-
(decayed_alpha, decayed_beta)
|
|
173
|
-
"""
|
|
174
|
-
new_alpha = max(ALPHA_FLOOR, alpha * DECAY_FACTOR)
|
|
175
|
-
new_beta = max(BETA_FLOOR, beta * DECAY_FACTOR)
|
|
176
|
-
return (new_alpha, new_beta)
|
|
177
|
-
|
|
178
|
-
# =========================================================================
|
|
179
|
-
# Signal Recording (Beta-Binomial Update)
|
|
180
|
-
# =========================================================================
|
|
181
|
-
|
|
182
|
-
def record_signal(
|
|
183
|
-
self,
|
|
184
|
-
agent_id: str,
|
|
185
|
-
signal_type: str,
|
|
186
|
-
context: Optional[dict] = None,
|
|
187
|
-
) -> bool:
|
|
188
|
-
"""
|
|
189
|
-
Record a trust signal for an agent using Beta-Binomial update.
|
|
190
|
-
|
|
191
|
-
Args:
|
|
192
|
-
agent_id: Agent that generated the signal
|
|
193
|
-
signal_type: One of SIGNAL_WEIGHTS keys
|
|
194
|
-
context: Additional context (memory_id, etc.)
|
|
195
|
-
|
|
196
|
-
Returns:
|
|
197
|
-
True if signal was recorded successfully
|
|
198
|
-
"""
|
|
199
|
-
if signal_type not in SIGNAL_WEIGHTS:
|
|
200
|
-
logger.warning("Unknown trust signal: %s", signal_type)
|
|
201
|
-
return False
|
|
202
|
-
|
|
203
|
-
direction, weight = SIGNAL_WEIGHTS[signal_type]
|
|
204
|
-
|
|
205
|
-
# Get current Beta parameters
|
|
206
|
-
alpha, beta = self._get_beta_params(agent_id)
|
|
207
|
-
old_score = alpha / (alpha + beta) if (alpha + beta) > 0 else 0.0
|
|
208
|
-
|
|
209
|
-
# Apply Beta-Binomial update
|
|
210
|
-
if direction == "positive":
|
|
211
|
-
alpha += weight
|
|
212
|
-
elif direction == "negative":
|
|
213
|
-
beta += weight
|
|
214
|
-
else: # neutral -- tiny alpha nudge
|
|
215
|
-
alpha += weight
|
|
216
|
-
|
|
217
|
-
# Apply periodic decay
|
|
218
|
-
count = self._signal_counts.get(agent_id, 0) + 1
|
|
219
|
-
self._signal_counts[agent_id] = count
|
|
220
|
-
|
|
221
|
-
if count % DECAY_INTERVAL == 0:
|
|
222
|
-
alpha, beta = self._apply_decay(agent_id, alpha, beta)
|
|
223
|
-
|
|
224
|
-
# Compute new trust score (posterior mean)
|
|
225
|
-
new_score = alpha / (alpha + beta) if (alpha + beta) > 0 else 0.0
|
|
226
|
-
|
|
227
|
-
# Compute delta for audit trail
|
|
228
|
-
delta = new_score - old_score
|
|
229
|
-
|
|
230
|
-
# Persist signal to audit trail
|
|
231
|
-
self._persist_signal(agent_id, signal_type, delta, old_score, new_score, context)
|
|
232
|
-
|
|
233
|
-
# Persist updated Beta parameters and derived trust_score
|
|
234
|
-
self._set_beta_params(agent_id, alpha, beta)
|
|
235
|
-
|
|
236
|
-
logger.debug(
|
|
237
|
-
"Trust signal: agent=%s, type=%s (%s, w=%.2f), "
|
|
238
|
-
"alpha=%.2f, beta=%.2f, score=%.4f->%.4f",
|
|
239
|
-
agent_id, signal_type, direction, weight,
|
|
240
|
-
alpha, beta, old_score, new_score
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
return True
|
|
244
|
-
|
|
245
|
-
def _persist_signal(self, agent_id, signal_type, delta, old_score, new_score, context):
|
|
246
|
-
"""Save signal to trust_signals table."""
|
|
247
|
-
try:
|
|
248
|
-
from db_connection_manager import DbConnectionManager
|
|
249
|
-
mgr = DbConnectionManager.get_instance(self.db_path)
|
|
250
|
-
|
|
251
|
-
def _insert(conn):
|
|
252
|
-
conn.execute('''
|
|
253
|
-
INSERT INTO trust_signals (agent_id, signal_type, delta, old_score, new_score, context)
|
|
254
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
255
|
-
''', (agent_id, signal_type, delta, old_score, new_score, json.dumps(context or {})))
|
|
256
|
-
conn.commit()
|
|
257
|
-
|
|
258
|
-
mgr.execute_write(_insert)
|
|
259
|
-
except Exception as e:
|
|
260
|
-
logger.error("Failed to persist trust signal: %s", e)
|
|
261
|
-
|
|
262
|
-
def _get_agent_trust(self, agent_id: str) -> Optional[float]:
|
|
263
|
-
"""Get current trust score from agent_registry."""
|
|
264
|
-
try:
|
|
265
|
-
from db_connection_manager import DbConnectionManager
|
|
266
|
-
mgr = DbConnectionManager.get_instance(self.db_path)
|
|
267
|
-
|
|
268
|
-
with mgr.read_connection() as conn:
|
|
269
|
-
cursor = conn.cursor()
|
|
270
|
-
cursor.execute(
|
|
271
|
-
"SELECT trust_score FROM agent_registry WHERE agent_id = ?",
|
|
272
|
-
(agent_id,)
|
|
273
|
-
)
|
|
274
|
-
row = cursor.fetchone()
|
|
275
|
-
return row[0] if row else None
|
|
276
|
-
except Exception:
|
|
277
|
-
return None
|
|
278
|
-
|
|
279
|
-
def _update_agent_trust(self, agent_id: str, new_score: float):
|
|
280
|
-
"""
|
|
281
|
-
Update trust score in agent_registry (legacy compatibility method).
|
|
282
|
-
|
|
283
|
-
In Beta-Binomial mode, _set_beta_params already updates trust_score
|
|
284
|
-
alongside alpha and beta. Kept for backward compatibility.
|
|
285
|
-
"""
|
|
286
|
-
try:
|
|
287
|
-
from db_connection_manager import DbConnectionManager
|
|
288
|
-
mgr = DbConnectionManager.get_instance(self.db_path)
|
|
289
|
-
|
|
290
|
-
def _update(conn):
|
|
291
|
-
conn.execute(
|
|
292
|
-
"UPDATE agent_registry SET trust_score = ? WHERE agent_id = ?",
|
|
293
|
-
(round(new_score, 4), agent_id)
|
|
294
|
-
)
|
|
295
|
-
conn.commit()
|
|
296
|
-
|
|
297
|
-
mgr.execute_write(_update)
|
|
298
|
-
except Exception as e:
|
|
299
|
-
logger.error("Failed to update agent trust: %s", e)
|
package/src/trust/signals.py
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""
|
|
5
|
-
High-level signal helpers and burst detection mixin for TrustScorer.
|
|
6
|
-
|
|
7
|
-
Contains: on_memory_created, on_memory_deleted, on_memory_recalled,
|
|
8
|
-
_track_write, _is_burst.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
import logging
|
|
12
|
-
from datetime import datetime, timedelta
|
|
13
|
-
from typing import Optional
|
|
14
|
-
|
|
15
|
-
from .constants import (
|
|
16
|
-
QUICK_DELETE_HOURS,
|
|
17
|
-
BURST_THRESHOLD,
|
|
18
|
-
BURST_WINDOW_MINUTES,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
logger = logging.getLogger("superlocalmemory.trust")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class TrustSignalsMixin:
|
|
25
|
-
"""Mixin providing high-level signal helpers and burst detection."""
|
|
26
|
-
|
|
27
|
-
# =========================================================================
|
|
28
|
-
# High-Level Signal Helpers (called from memory_store_v2 / mcp_server)
|
|
29
|
-
# =========================================================================
|
|
30
|
-
|
|
31
|
-
def on_memory_created(self, agent_id: str, memory_id: int, importance: int = 5):
|
|
32
|
-
"""Record signals when a memory is created."""
|
|
33
|
-
# Track write timestamp for burst detection
|
|
34
|
-
self._track_write(agent_id)
|
|
35
|
-
|
|
36
|
-
if importance >= 7:
|
|
37
|
-
self.record_signal(agent_id, "high_importance_write",
|
|
38
|
-
context={"memory_id": memory_id, "importance": importance})
|
|
39
|
-
else:
|
|
40
|
-
self.record_signal(agent_id, "normal_write",
|
|
41
|
-
context={"memory_id": memory_id})
|
|
42
|
-
|
|
43
|
-
# Check for burst pattern
|
|
44
|
-
if self._is_burst(agent_id):
|
|
45
|
-
self.record_signal(agent_id, "high_volume_burst",
|
|
46
|
-
context={"memory_id": memory_id})
|
|
47
|
-
|
|
48
|
-
def on_memory_deleted(self, agent_id: str, memory_id: int, created_at: Optional[str] = None):
|
|
49
|
-
"""Record signals when a memory is deleted."""
|
|
50
|
-
if created_at:
|
|
51
|
-
try:
|
|
52
|
-
created = datetime.fromisoformat(created_at)
|
|
53
|
-
age_hours = (datetime.now() - created).total_seconds() / 3600
|
|
54
|
-
if age_hours < QUICK_DELETE_HOURS:
|
|
55
|
-
self.record_signal(agent_id, "quick_delete",
|
|
56
|
-
context={"memory_id": memory_id, "age_hours": round(age_hours, 2)})
|
|
57
|
-
return
|
|
58
|
-
except (ValueError, TypeError):
|
|
59
|
-
pass
|
|
60
|
-
|
|
61
|
-
# Normal delete (no negative signal)
|
|
62
|
-
self.record_signal(agent_id, "normal_write",
|
|
63
|
-
context={"memory_id": memory_id, "action": "delete"})
|
|
64
|
-
|
|
65
|
-
def on_memory_recalled(self, agent_id: str, memory_id: int, created_by: Optional[str] = None):
|
|
66
|
-
"""Record signals when a memory is recalled."""
|
|
67
|
-
if created_by and created_by != agent_id:
|
|
68
|
-
# Cross-agent validation: another agent found this memory useful
|
|
69
|
-
self.record_signal(created_by, "memory_recalled_by_others",
|
|
70
|
-
context={"memory_id": memory_id, "recalled_by": agent_id})
|
|
71
|
-
|
|
72
|
-
self.record_signal(agent_id, "normal_recall",
|
|
73
|
-
context={"memory_id": memory_id})
|
|
74
|
-
|
|
75
|
-
# =========================================================================
|
|
76
|
-
# Burst Detection
|
|
77
|
-
# =========================================================================
|
|
78
|
-
|
|
79
|
-
def _track_write(self, agent_id: str):
|
|
80
|
-
"""Track a write timestamp for burst detection."""
|
|
81
|
-
now = datetime.now()
|
|
82
|
-
with self._timestamps_lock:
|
|
83
|
-
if agent_id not in self._write_timestamps:
|
|
84
|
-
self._write_timestamps[agent_id] = []
|
|
85
|
-
timestamps = self._write_timestamps[agent_id]
|
|
86
|
-
timestamps.append(now)
|
|
87
|
-
# Keep only recent timestamps (within burst window)
|
|
88
|
-
cutoff = now - timedelta(minutes=BURST_WINDOW_MINUTES)
|
|
89
|
-
self._write_timestamps[agent_id] = [t for t in timestamps if t > cutoff]
|
|
90
|
-
|
|
91
|
-
def _is_burst(self, agent_id: str) -> bool:
|
|
92
|
-
"""Check if agent is in a burst write pattern."""
|
|
93
|
-
with self._timestamps_lock:
|
|
94
|
-
timestamps = self._write_timestamps.get(agent_id, [])
|
|
95
|
-
return len(timestamps) > BURST_THRESHOLD
|
package/src/trust_scorer.py
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""
|
|
5
|
-
Backward-compatible shim -- delegates to src/trust/ package.
|
|
6
|
-
|
|
7
|
-
All public symbols are re-exported so existing imports like
|
|
8
|
-
``from trust_scorer import TrustScorer`` continue to work unchanged.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
# Re-export everything from the trust package
|
|
12
|
-
from trust.constants import ( # noqa: F401
|
|
13
|
-
SIGNAL_WEIGHTS,
|
|
14
|
-
SIGNAL_DELTAS,
|
|
15
|
-
INITIAL_ALPHA,
|
|
16
|
-
INITIAL_BETA,
|
|
17
|
-
DECAY_FACTOR,
|
|
18
|
-
DECAY_INTERVAL,
|
|
19
|
-
ALPHA_FLOOR,
|
|
20
|
-
BETA_FLOOR,
|
|
21
|
-
QUICK_DELETE_HOURS,
|
|
22
|
-
BURST_THRESHOLD,
|
|
23
|
-
BURST_WINDOW_MINUTES,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
from trust.schema import init_trust_schema # noqa: F401
|
|
27
|
-
|
|
28
|
-
from trust.scorer import TrustScorer # noqa: F401
|
|
29
|
-
|
|
30
|
-
__all__ = [
|
|
31
|
-
"TrustScorer",
|
|
32
|
-
"SIGNAL_WEIGHTS",
|
|
33
|
-
"SIGNAL_DELTAS",
|
|
34
|
-
"INITIAL_ALPHA",
|
|
35
|
-
"INITIAL_BETA",
|
|
36
|
-
"DECAY_FACTOR",
|
|
37
|
-
"DECAY_INTERVAL",
|
|
38
|
-
"ALPHA_FLOOR",
|
|
39
|
-
"BETA_FLOOR",
|
|
40
|
-
"QUICK_DELETE_HOURS",
|
|
41
|
-
"BURST_THRESHOLD",
|
|
42
|
-
"BURST_WINDOW_MINUTES",
|
|
43
|
-
"init_trust_schema",
|
|
44
|
-
]
|