superlocalmemory 2.8.5 → 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.
Files changed (434) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +9 -1
  3. package/NOTICE +63 -0
  4. package/README.md +165 -480
  5. package/bin/slm +17 -449
  6. package/bin/slm-npm +2 -2
  7. package/bin/slm.bat +4 -2
  8. package/conftest.py +5 -0
  9. package/docs/api-reference.md +284 -0
  10. package/docs/architecture.md +149 -0
  11. package/docs/auto-memory.md +150 -0
  12. package/docs/cli-reference.md +276 -0
  13. package/docs/compliance.md +191 -0
  14. package/docs/configuration.md +182 -0
  15. package/docs/getting-started.md +102 -0
  16. package/docs/ide-setup.md +261 -0
  17. package/docs/mcp-tools.md +220 -0
  18. package/docs/migration-from-v2.md +170 -0
  19. package/docs/profiles.md +173 -0
  20. package/docs/troubleshooting.md +310 -0
  21. package/{configs → ide/configs}/antigravity-mcp.json +3 -3
  22. package/ide/configs/chatgpt-desktop-mcp.json +16 -0
  23. package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
  24. package/{configs → ide/configs}/codex-mcp.toml +4 -4
  25. package/{configs → ide/configs}/continue-mcp.yaml +4 -3
  26. package/{configs → ide/configs}/continue-skills.yaml +6 -6
  27. package/ide/configs/cursor-mcp.json +15 -0
  28. package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
  29. package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
  30. package/{configs → ide/configs}/opencode-mcp.json +2 -2
  31. package/{configs → ide/configs}/perplexity-mcp.json +2 -2
  32. package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
  33. package/{configs → ide/configs}/windsurf-mcp.json +3 -3
  34. package/{configs → ide/configs}/zed-mcp.json +2 -2
  35. package/{hooks → ide/hooks}/context-hook.js +9 -20
  36. package/ide/hooks/memory-list-skill.js +70 -0
  37. package/ide/hooks/memory-profile-skill.js +101 -0
  38. package/ide/hooks/memory-recall-skill.js +62 -0
  39. package/ide/hooks/memory-remember-skill.js +68 -0
  40. package/ide/hooks/memory-reset-skill.js +160 -0
  41. package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
  42. package/ide/integrations/langchain/README.md +106 -0
  43. package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
  44. package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
  45. package/ide/integrations/langchain/pyproject.toml +38 -0
  46. package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
  47. package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
  48. package/ide/integrations/langchain/tests/test_security.py +117 -0
  49. package/ide/integrations/llamaindex/README.md +81 -0
  50. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
  51. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
  52. package/ide/integrations/llamaindex/pyproject.toml +43 -0
  53. package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
  54. package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
  55. package/ide/integrations/llamaindex/tests/test_security.py +241 -0
  56. package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
  57. package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
  58. package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
  59. package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
  60. package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
  61. package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
  62. package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
  63. package/package.json +13 -22
  64. package/pyproject.toml +85 -0
  65. package/scripts/build-dmg.sh +417 -0
  66. package/scripts/install-skills.ps1 +334 -0
  67. package/{install.ps1 → scripts/install.ps1} +36 -4
  68. package/{install.sh → scripts/install.sh} +14 -13
  69. package/scripts/postinstall.js +2 -2
  70. package/scripts/start-dashboard.ps1 +52 -0
  71. package/scripts/start-dashboard.sh +41 -0
  72. package/scripts/sync-wiki.ps1 +127 -0
  73. package/scripts/sync-wiki.sh +82 -0
  74. package/scripts/test-dmg.sh +161 -0
  75. package/scripts/test-npm-package.ps1 +252 -0
  76. package/scripts/test-npm-package.sh +207 -0
  77. package/scripts/verify-install.ps1 +294 -0
  78. package/scripts/verify-install.sh +266 -0
  79. package/src/superlocalmemory/__init__.py +0 -0
  80. package/src/superlocalmemory/attribution/__init__.py +9 -0
  81. package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
  82. package/src/superlocalmemory/attribution/signer.py +153 -0
  83. package/src/superlocalmemory/attribution/watermark.py +189 -0
  84. package/src/superlocalmemory/cli/__init__.py +5 -0
  85. package/src/superlocalmemory/cli/commands.py +245 -0
  86. package/src/superlocalmemory/cli/main.py +89 -0
  87. package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
  88. package/src/superlocalmemory/cli/post_install.py +99 -0
  89. package/src/superlocalmemory/cli/setup_wizard.py +129 -0
  90. package/src/superlocalmemory/compliance/__init__.py +0 -0
  91. package/src/superlocalmemory/compliance/abac.py +204 -0
  92. package/src/superlocalmemory/compliance/audit.py +314 -0
  93. package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
  94. package/src/superlocalmemory/compliance/gdpr.py +294 -0
  95. package/src/superlocalmemory/compliance/lifecycle.py +158 -0
  96. package/src/superlocalmemory/compliance/retention.py +232 -0
  97. package/src/superlocalmemory/compliance/scheduler.py +148 -0
  98. package/src/superlocalmemory/core/__init__.py +0 -0
  99. package/src/superlocalmemory/core/config.py +391 -0
  100. package/src/superlocalmemory/core/embeddings.py +293 -0
  101. package/src/superlocalmemory/core/engine.py +701 -0
  102. package/src/superlocalmemory/core/hooks.py +65 -0
  103. package/src/superlocalmemory/core/maintenance.py +172 -0
  104. package/src/superlocalmemory/core/modes.py +140 -0
  105. package/src/superlocalmemory/core/profiles.py +234 -0
  106. package/src/superlocalmemory/core/registry.py +117 -0
  107. package/src/superlocalmemory/dynamics/__init__.py +0 -0
  108. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
  109. package/src/superlocalmemory/encoding/__init__.py +0 -0
  110. package/src/superlocalmemory/encoding/consolidator.py +485 -0
  111. package/src/superlocalmemory/encoding/emotional.py +125 -0
  112. package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
  113. package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
  114. package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
  115. package/src/superlocalmemory/encoding/foresight.py +91 -0
  116. package/src/superlocalmemory/encoding/graph_builder.py +302 -0
  117. package/src/superlocalmemory/encoding/observation_builder.py +160 -0
  118. package/src/superlocalmemory/encoding/scene_builder.py +183 -0
  119. package/src/superlocalmemory/encoding/signal_inference.py +90 -0
  120. package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
  121. package/src/superlocalmemory/encoding/type_router.py +235 -0
  122. package/src/superlocalmemory/hooks/__init__.py +3 -0
  123. package/src/superlocalmemory/hooks/auto_capture.py +111 -0
  124. package/src/superlocalmemory/hooks/auto_recall.py +93 -0
  125. package/src/superlocalmemory/hooks/ide_connector.py +204 -0
  126. package/src/superlocalmemory/hooks/rules_engine.py +99 -0
  127. package/src/superlocalmemory/infra/__init__.py +3 -0
  128. package/src/superlocalmemory/infra/auth_middleware.py +82 -0
  129. package/src/superlocalmemory/infra/backup.py +317 -0
  130. package/src/superlocalmemory/infra/cache_manager.py +267 -0
  131. package/src/superlocalmemory/infra/event_bus.py +381 -0
  132. package/src/superlocalmemory/infra/rate_limiter.py +135 -0
  133. package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
  134. package/src/superlocalmemory/learning/__init__.py +0 -0
  135. package/src/superlocalmemory/learning/adaptive.py +172 -0
  136. package/src/superlocalmemory/learning/behavioral.py +490 -0
  137. package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
  138. package/src/superlocalmemory/learning/bootstrap.py +298 -0
  139. package/src/superlocalmemory/learning/cross_project.py +399 -0
  140. package/src/superlocalmemory/learning/database.py +376 -0
  141. package/src/superlocalmemory/learning/engagement.py +323 -0
  142. package/src/superlocalmemory/learning/features.py +138 -0
  143. package/src/superlocalmemory/learning/feedback.py +316 -0
  144. package/src/superlocalmemory/learning/outcomes.py +255 -0
  145. package/src/superlocalmemory/learning/project_context.py +366 -0
  146. package/src/superlocalmemory/learning/ranker.py +155 -0
  147. package/src/superlocalmemory/learning/source_quality.py +303 -0
  148. package/src/superlocalmemory/learning/workflows.py +309 -0
  149. package/src/superlocalmemory/llm/__init__.py +0 -0
  150. package/src/superlocalmemory/llm/backbone.py +316 -0
  151. package/src/superlocalmemory/math/__init__.py +0 -0
  152. package/src/superlocalmemory/math/fisher.py +356 -0
  153. package/src/superlocalmemory/math/langevin.py +398 -0
  154. package/src/superlocalmemory/math/sheaf.py +257 -0
  155. package/src/superlocalmemory/mcp/__init__.py +0 -0
  156. package/src/superlocalmemory/mcp/resources.py +245 -0
  157. package/src/superlocalmemory/mcp/server.py +61 -0
  158. package/src/superlocalmemory/mcp/tools.py +18 -0
  159. package/src/superlocalmemory/mcp/tools_core.py +305 -0
  160. package/src/superlocalmemory/mcp/tools_v28.py +223 -0
  161. package/src/superlocalmemory/mcp/tools_v3.py +286 -0
  162. package/src/superlocalmemory/retrieval/__init__.py +0 -0
  163. package/src/superlocalmemory/retrieval/agentic.py +295 -0
  164. package/src/superlocalmemory/retrieval/ann_index.py +223 -0
  165. package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
  166. package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
  167. package/src/superlocalmemory/retrieval/engine.py +390 -0
  168. package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
  169. package/src/superlocalmemory/retrieval/fusion.py +78 -0
  170. package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
  171. package/src/superlocalmemory/retrieval/reranker.py +154 -0
  172. package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
  173. package/src/superlocalmemory/retrieval/strategy.py +96 -0
  174. package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
  175. package/src/superlocalmemory/server/__init__.py +1 -0
  176. package/src/superlocalmemory/server/api.py +248 -0
  177. package/src/superlocalmemory/server/routes/__init__.py +4 -0
  178. package/src/superlocalmemory/server/routes/agents.py +107 -0
  179. package/src/superlocalmemory/server/routes/backup.py +91 -0
  180. package/src/superlocalmemory/server/routes/behavioral.py +127 -0
  181. package/src/superlocalmemory/server/routes/compliance.py +160 -0
  182. package/src/superlocalmemory/server/routes/data_io.py +188 -0
  183. package/src/superlocalmemory/server/routes/events.py +183 -0
  184. package/src/superlocalmemory/server/routes/helpers.py +85 -0
  185. package/src/superlocalmemory/server/routes/learning.py +273 -0
  186. package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
  187. package/src/superlocalmemory/server/routes/memories.py +399 -0
  188. package/src/superlocalmemory/server/routes/profiles.py +219 -0
  189. package/src/superlocalmemory/server/routes/stats.py +346 -0
  190. package/src/superlocalmemory/server/routes/v3_api.py +365 -0
  191. package/src/superlocalmemory/server/routes/ws.py +82 -0
  192. package/src/superlocalmemory/server/security_middleware.py +57 -0
  193. package/src/superlocalmemory/server/ui.py +245 -0
  194. package/src/superlocalmemory/storage/__init__.py +0 -0
  195. package/src/superlocalmemory/storage/access_control.py +182 -0
  196. package/src/superlocalmemory/storage/database.py +594 -0
  197. package/src/superlocalmemory/storage/migrations.py +303 -0
  198. package/src/superlocalmemory/storage/models.py +406 -0
  199. package/src/superlocalmemory/storage/schema.py +726 -0
  200. package/src/superlocalmemory/storage/v2_migrator.py +317 -0
  201. package/src/superlocalmemory/trust/__init__.py +0 -0
  202. package/src/superlocalmemory/trust/gate.py +130 -0
  203. package/src/superlocalmemory/trust/provenance.py +124 -0
  204. package/src/superlocalmemory/trust/scorer.py +347 -0
  205. package/src/superlocalmemory/trust/signals.py +153 -0
  206. package/ui/index.html +278 -5
  207. package/ui/js/auto-settings.js +70 -0
  208. package/ui/js/dashboard.js +90 -0
  209. package/ui/js/fact-detail.js +92 -0
  210. package/ui/js/feedback.js +2 -2
  211. package/ui/js/ide-status.js +102 -0
  212. package/ui/js/math-health.js +98 -0
  213. package/ui/js/recall-lab.js +127 -0
  214. package/ui/js/settings.js +2 -2
  215. package/ui/js/trust-dashboard.js +73 -0
  216. package/api_server.py +0 -724
  217. package/bin/aider-smart +0 -72
  218. package/bin/superlocalmemoryv2-learning +0 -4
  219. package/bin/superlocalmemoryv2-list +0 -3
  220. package/bin/superlocalmemoryv2-patterns +0 -4
  221. package/bin/superlocalmemoryv2-profile +0 -3
  222. package/bin/superlocalmemoryv2-recall +0 -3
  223. package/bin/superlocalmemoryv2-remember +0 -3
  224. package/bin/superlocalmemoryv2-reset +0 -3
  225. package/bin/superlocalmemoryv2-status +0 -3
  226. package/configs/chatgpt-desktop-mcp.json +0 -16
  227. package/configs/cursor-mcp.json +0 -15
  228. package/docs/SECURITY-QUICK-REFERENCE.md +0 -214
  229. package/hooks/memory-list-skill.js +0 -139
  230. package/hooks/memory-profile-skill.js +0 -273
  231. package/hooks/memory-recall-skill.js +0 -114
  232. package/hooks/memory-remember-skill.js +0 -127
  233. package/hooks/memory-reset-skill.js +0 -274
  234. package/mcp_server.py +0 -1800
  235. package/requirements-core.txt +0 -22
  236. package/requirements-learning.txt +0 -12
  237. package/requirements.txt +0 -12
  238. package/src/agent_registry.py +0 -411
  239. package/src/auth_middleware.py +0 -61
  240. package/src/auto_backup.py +0 -459
  241. package/src/behavioral/__init__.py +0 -49
  242. package/src/behavioral/behavioral_listener.py +0 -203
  243. package/src/behavioral/behavioral_patterns.py +0 -275
  244. package/src/behavioral/cross_project_transfer.py +0 -206
  245. package/src/behavioral/outcome_inference.py +0 -194
  246. package/src/behavioral/outcome_tracker.py +0 -193
  247. package/src/behavioral/tests/__init__.py +0 -4
  248. package/src/behavioral/tests/test_behavioral_integration.py +0 -108
  249. package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
  250. package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
  251. package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
  252. package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
  253. package/src/behavioral/tests/test_outcome_inference.py +0 -107
  254. package/src/behavioral/tests/test_outcome_tracker.py +0 -96
  255. package/src/cache_manager.py +0 -518
  256. package/src/compliance/__init__.py +0 -48
  257. package/src/compliance/abac_engine.py +0 -149
  258. package/src/compliance/abac_middleware.py +0 -116
  259. package/src/compliance/audit_db.py +0 -215
  260. package/src/compliance/audit_logger.py +0 -148
  261. package/src/compliance/retention_manager.py +0 -289
  262. package/src/compliance/retention_scheduler.py +0 -186
  263. package/src/compliance/tests/__init__.py +0 -4
  264. package/src/compliance/tests/test_abac_enforcement.py +0 -95
  265. package/src/compliance/tests/test_abac_engine.py +0 -124
  266. package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
  267. package/src/compliance/tests/test_audit_db.py +0 -123
  268. package/src/compliance/tests/test_audit_logger.py +0 -98
  269. package/src/compliance/tests/test_mcp_audit.py +0 -128
  270. package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
  271. package/src/compliance/tests/test_retention_manager.py +0 -131
  272. package/src/compliance/tests/test_retention_scheduler.py +0 -99
  273. package/src/compression/__init__.py +0 -25
  274. package/src/compression/cli.py +0 -150
  275. package/src/compression/cold_storage.py +0 -217
  276. package/src/compression/config.py +0 -72
  277. package/src/compression/orchestrator.py +0 -133
  278. package/src/compression/tier2_compressor.py +0 -228
  279. package/src/compression/tier3_compressor.py +0 -153
  280. package/src/compression/tier_classifier.py +0 -148
  281. package/src/db_connection_manager.py +0 -536
  282. package/src/embedding_engine.py +0 -63
  283. package/src/embeddings/__init__.py +0 -47
  284. package/src/embeddings/cache.py +0 -70
  285. package/src/embeddings/cli.py +0 -113
  286. package/src/embeddings/constants.py +0 -47
  287. package/src/embeddings/database.py +0 -91
  288. package/src/embeddings/engine.py +0 -247
  289. package/src/embeddings/model_loader.py +0 -145
  290. package/src/event_bus.py +0 -562
  291. package/src/graph/__init__.py +0 -36
  292. package/src/graph/build_helpers.py +0 -74
  293. package/src/graph/cli.py +0 -87
  294. package/src/graph/cluster_builder.py +0 -188
  295. package/src/graph/cluster_summary.py +0 -148
  296. package/src/graph/constants.py +0 -47
  297. package/src/graph/edge_builder.py +0 -162
  298. package/src/graph/entity_extractor.py +0 -95
  299. package/src/graph/graph_core.py +0 -226
  300. package/src/graph/graph_search.py +0 -231
  301. package/src/graph/hierarchical.py +0 -207
  302. package/src/graph/schema.py +0 -99
  303. package/src/graph_engine.py +0 -52
  304. package/src/hnsw_index.py +0 -628
  305. package/src/hybrid_search.py +0 -46
  306. package/src/learning/__init__.py +0 -217
  307. package/src/learning/adaptive_ranker.py +0 -682
  308. package/src/learning/bootstrap/__init__.py +0 -69
  309. package/src/learning/bootstrap/constants.py +0 -93
  310. package/src/learning/bootstrap/db_queries.py +0 -316
  311. package/src/learning/bootstrap/sampling.py +0 -82
  312. package/src/learning/bootstrap/text_utils.py +0 -71
  313. package/src/learning/cross_project_aggregator.py +0 -857
  314. package/src/learning/db/__init__.py +0 -40
  315. package/src/learning/db/constants.py +0 -44
  316. package/src/learning/db/schema.py +0 -279
  317. package/src/learning/engagement_tracker.py +0 -628
  318. package/src/learning/feature_extractor.py +0 -708
  319. package/src/learning/feedback_collector.py +0 -806
  320. package/src/learning/learning_db.py +0 -915
  321. package/src/learning/project_context_manager.py +0 -572
  322. package/src/learning/ranking/__init__.py +0 -33
  323. package/src/learning/ranking/constants.py +0 -84
  324. package/src/learning/ranking/helpers.py +0 -278
  325. package/src/learning/source_quality_scorer.py +0 -676
  326. package/src/learning/synthetic_bootstrap.py +0 -755
  327. package/src/learning/tests/test_adaptive_ranker.py +0 -325
  328. package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
  329. package/src/learning/tests/test_aggregator.py +0 -306
  330. package/src/learning/tests/test_auto_retrain_v28.py +0 -35
  331. package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
  332. package/src/learning/tests/test_feature_extractor_v28.py +0 -93
  333. package/src/learning/tests/test_feedback_collector.py +0 -294
  334. package/src/learning/tests/test_learning_db.py +0 -602
  335. package/src/learning/tests/test_learning_db_v28.py +0 -110
  336. package/src/learning/tests/test_learning_init_v28.py +0 -48
  337. package/src/learning/tests/test_outcome_signals.py +0 -48
  338. package/src/learning/tests/test_project_context.py +0 -292
  339. package/src/learning/tests/test_schema_migration.py +0 -319
  340. package/src/learning/tests/test_signal_inference.py +0 -397
  341. package/src/learning/tests/test_source_quality.py +0 -351
  342. package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
  343. package/src/learning/tests/test_workflow_miner.py +0 -318
  344. package/src/learning/workflow_pattern_miner.py +0 -655
  345. package/src/lifecycle/__init__.py +0 -54
  346. package/src/lifecycle/bounded_growth.py +0 -239
  347. package/src/lifecycle/compaction_engine.py +0 -226
  348. package/src/lifecycle/lifecycle_engine.py +0 -355
  349. package/src/lifecycle/lifecycle_evaluator.py +0 -257
  350. package/src/lifecycle/lifecycle_scheduler.py +0 -130
  351. package/src/lifecycle/retention_policy.py +0 -285
  352. package/src/lifecycle/tests/test_bounded_growth.py +0 -193
  353. package/src/lifecycle/tests/test_compaction.py +0 -179
  354. package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
  355. package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
  356. package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
  357. package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
  358. package/src/lifecycle/tests/test_mcp_compact.py +0 -149
  359. package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
  360. package/src/lifecycle/tests/test_retention_policy.py +0 -162
  361. package/src/mcp_tools_v28.py +0 -281
  362. package/src/memory/__init__.py +0 -36
  363. package/src/memory/cli.py +0 -205
  364. package/src/memory/constants.py +0 -39
  365. package/src/memory/helpers.py +0 -28
  366. package/src/memory/schema.py +0 -166
  367. package/src/memory-profiles.py +0 -595
  368. package/src/memory-reset.py +0 -491
  369. package/src/memory_compression.py +0 -989
  370. package/src/memory_store_v2.py +0 -1155
  371. package/src/migrate_v1_to_v2.py +0 -629
  372. package/src/pattern_learner.py +0 -34
  373. package/src/patterns/__init__.py +0 -24
  374. package/src/patterns/analyzers.py +0 -251
  375. package/src/patterns/learner.py +0 -271
  376. package/src/patterns/scoring.py +0 -171
  377. package/src/patterns/store.py +0 -225
  378. package/src/patterns/terminology.py +0 -140
  379. package/src/provenance_tracker.py +0 -312
  380. package/src/qualixar_attribution.py +0 -139
  381. package/src/qualixar_watermark.py +0 -78
  382. package/src/query_optimizer.py +0 -511
  383. package/src/rate_limiter.py +0 -83
  384. package/src/search/__init__.py +0 -20
  385. package/src/search/cli.py +0 -77
  386. package/src/search/constants.py +0 -26
  387. package/src/search/engine.py +0 -241
  388. package/src/search/fusion.py +0 -122
  389. package/src/search/index_loader.py +0 -114
  390. package/src/search/methods.py +0 -162
  391. package/src/search_engine_v2.py +0 -401
  392. package/src/setup_validator.py +0 -482
  393. package/src/subscription_manager.py +0 -391
  394. package/src/tree/__init__.py +0 -59
  395. package/src/tree/builder.py +0 -185
  396. package/src/tree/nodes.py +0 -202
  397. package/src/tree/queries.py +0 -257
  398. package/src/tree/schema.py +0 -80
  399. package/src/tree_manager.py +0 -19
  400. package/src/trust/__init__.py +0 -45
  401. package/src/trust/constants.py +0 -66
  402. package/src/trust/queries.py +0 -157
  403. package/src/trust/schema.py +0 -95
  404. package/src/trust/scorer.py +0 -299
  405. package/src/trust/signals.py +0 -95
  406. package/src/trust_scorer.py +0 -44
  407. package/ui/app.js +0 -1588
  408. package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
  409. package/ui/js/graph-cytoscape.js +0 -1168
  410. package/ui/js/graph-d3-backup.js +0 -32
  411. package/ui/js/graph.js +0 -32
  412. package/ui_server.py +0 -266
  413. /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
  414. /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
  415. /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
  416. /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
  417. /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
  418. /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
  419. /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
  420. /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
  421. /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
  422. /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
  423. /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
  424. /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
  425. /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
  426. /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
  427. /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
  428. /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
  429. /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
  430. /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
  431. /package/{completions → ide/completions}/slm.bash +0 -0
  432. /package/{completions → ide/completions}/slm.zsh +0 -0
  433. /package/{configs → ide/configs}/cody-commands.json +0 -0
  434. /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
@@ -0,0 +1,303 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SuperLocalMemory V3 — Database Migrations.
6
+
7
+ Handles schema versioning and V1 (slm_alpha) → Innovation migration.
8
+ Preserves existing data while upgrading schema structure.
9
+
10
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import json
16
+ import logging
17
+ import shutil
18
+ import sqlite3
19
+ from datetime import UTC, datetime
20
+ from pathlib import Path
21
+ from typing import Any
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+ CURRENT_SCHEMA_VERSION = 1 # Innovation v1
26
+
27
+
28
+ def get_schema_version(conn: sqlite3.Connection) -> int:
29
+ """Read current schema version. Returns 0 if no version table."""
30
+ try:
31
+ row = conn.execute(
32
+ "SELECT version FROM schema_version ORDER BY applied_at DESC LIMIT 1"
33
+ ).fetchone()
34
+ return int(row[0]) if row else 0
35
+ except sqlite3.OperationalError:
36
+ return 0
37
+
38
+
39
+ def set_schema_version(conn: sqlite3.Connection, version: int) -> None:
40
+ """Record a schema version upgrade."""
41
+ conn.execute(
42
+ "INSERT INTO schema_version (version, applied_at, description) VALUES (?, ?, ?)",
43
+ (version, datetime.now(UTC).isoformat(), f"Migration to v{version}"),
44
+ )
45
+
46
+
47
+ def needs_migration(db_path: Path) -> bool:
48
+ """Check if database needs migration."""
49
+ if not db_path.exists():
50
+ return False
51
+ conn = sqlite3.connect(str(db_path))
52
+ try:
53
+ version = get_schema_version(conn)
54
+ return version < CURRENT_SCHEMA_VERSION
55
+ finally:
56
+ conn.close()
57
+
58
+
59
+ def is_v1_database(db_path: Path) -> bool:
60
+ """Detect if this is a V1 (slm_alpha) database by checking for V1-specific tables."""
61
+ if not db_path.exists():
62
+ return False
63
+ conn = sqlite3.connect(str(db_path))
64
+ try:
65
+ tables = {
66
+ row[0]
67
+ for row in conn.execute(
68
+ "SELECT name FROM sqlite_master WHERE type='table'"
69
+ ).fetchall()
70
+ }
71
+ # V1 markers: episodic_memory table + no schema_version
72
+ return "episodic_memory" in tables and "schema_version" not in tables
73
+ finally:
74
+ conn.close()
75
+
76
+
77
+ def backup_database(db_path: Path) -> Path:
78
+ """Create timestamped backup before migration."""
79
+ timestamp = datetime.now(UTC).strftime("%Y%m%d_%H%M%S")
80
+ backup_path = db_path.with_suffix(f".backup_{timestamp}.db")
81
+ shutil.copy2(str(db_path), str(backup_path))
82
+ logger.info("Database backed up to %s", backup_path)
83
+ return backup_path
84
+
85
+
86
+ def migrate_v1_to_innovation(
87
+ v1_db_path: Path,
88
+ innovation_db_path: Path,
89
+ profile_id: str = "default",
90
+ ) -> dict[str, Any]:
91
+ """Migrate V1 (slm_alpha) database to Innovation schema.
92
+
93
+ Preserves all memories and facts. Creates proper typed stores.
94
+ Returns migration statistics.
95
+ """
96
+ from superlocalmemory.storage import schema
97
+
98
+ stats: dict[str, Any] = {
99
+ "memories_migrated": 0,
100
+ "facts_migrated": 0,
101
+ "entities_migrated": 0,
102
+ "edges_migrated": 0,
103
+ "errors": [],
104
+ }
105
+
106
+ if not v1_db_path.exists():
107
+ stats["errors"].append(f"V1 database not found: {v1_db_path}")
108
+ return stats
109
+
110
+ # Backup V1 database
111
+ backup_database(v1_db_path)
112
+
113
+ # Create Innovation database with clean schema
114
+ new_conn = sqlite3.connect(str(innovation_db_path))
115
+ new_conn.row_factory = sqlite3.Row
116
+ try:
117
+ new_conn.execute("PRAGMA foreign_keys=ON")
118
+ schema.create_all_tables(new_conn)
119
+
120
+ # Ensure default profile exists
121
+ new_conn.execute(
122
+ "INSERT OR IGNORE INTO profiles (profile_id, name, description, mode, created_at) "
123
+ "VALUES (?, ?, ?, ?, ?)",
124
+ (profile_id, profile_id, "Migrated from V1", "a", datetime.now(UTC).isoformat()),
125
+ )
126
+
127
+ # Open V1 database
128
+ v1_conn = sqlite3.connect(str(v1_db_path))
129
+ v1_conn.row_factory = sqlite3.Row
130
+ try:
131
+ stats = _migrate_memories(v1_conn, new_conn, profile_id, stats)
132
+ stats = _migrate_facts(v1_conn, new_conn, profile_id, stats)
133
+ stats = _migrate_entities(v1_conn, new_conn, profile_id, stats)
134
+ stats = _migrate_edges(v1_conn, new_conn, profile_id, stats)
135
+ new_conn.commit()
136
+ finally:
137
+ v1_conn.close()
138
+
139
+ set_schema_version(new_conn, CURRENT_SCHEMA_VERSION)
140
+ new_conn.commit()
141
+ logger.info("Migration complete: %s", stats)
142
+
143
+ finally:
144
+ new_conn.close()
145
+
146
+ return stats
147
+
148
+
149
+ def _migrate_memories(
150
+ v1: sqlite3.Connection,
151
+ new: sqlite3.Connection,
152
+ profile_id: str,
153
+ stats: dict[str, Any],
154
+ ) -> dict[str, Any]:
155
+ """Migrate episodic_memory → memories table."""
156
+ try:
157
+ rows = v1.execute("SELECT * FROM episodic_memory").fetchall()
158
+ except sqlite3.OperationalError:
159
+ stats["errors"].append("No episodic_memory table in V1")
160
+ return stats
161
+
162
+ for row in rows:
163
+ d = dict(row)
164
+ try:
165
+ new.execute(
166
+ "INSERT OR IGNORE INTO memories "
167
+ "(memory_id, profile_id, content, session_id, speaker, role, "
168
+ "session_date, created_at, metadata) "
169
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
170
+ (
171
+ d.get("memory_id", d.get("id", "")),
172
+ profile_id,
173
+ d.get("content", ""),
174
+ d.get("session_id", ""),
175
+ d.get("speaker", ""),
176
+ d.get("role", ""),
177
+ d.get("session_date"),
178
+ d.get("created_at", datetime.now(UTC).isoformat()),
179
+ json.dumps({"migrated_from": "v1"}),
180
+ ),
181
+ )
182
+ stats["memories_migrated"] += 1
183
+ except sqlite3.Error as exc:
184
+ stats["errors"].append(f"Memory {d.get('id', '?')}: {exc}")
185
+
186
+ return stats
187
+
188
+
189
+ def _migrate_facts(
190
+ v1: sqlite3.Connection,
191
+ new: sqlite3.Connection,
192
+ profile_id: str,
193
+ stats: dict[str, Any],
194
+ ) -> dict[str, Any]:
195
+ """Migrate semantic_facts → facts table."""
196
+ try:
197
+ rows = v1.execute("SELECT * FROM semantic_facts").fetchall()
198
+ except sqlite3.OperationalError:
199
+ return stats
200
+
201
+ for row in rows:
202
+ d = dict(row)
203
+ try:
204
+ new.execute(
205
+ "INSERT OR IGNORE INTO facts "
206
+ "(fact_id, memory_id, profile_id, content, fact_type, "
207
+ "entities, canonical_entities, confidence, importance, "
208
+ "evidence_count, access_count, created_at) "
209
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
210
+ (
211
+ d.get("fact_id", d.get("id", "")),
212
+ d.get("memory_id", ""),
213
+ profile_id,
214
+ d.get("content", d.get("fact", "")),
215
+ d.get("fact_type", "semantic"),
216
+ d.get("entities_json", "[]"),
217
+ d.get("canonical_entities_json", "[]"),
218
+ d.get("confidence", 1.0),
219
+ d.get("importance", 0.5),
220
+ d.get("evidence_count", 1),
221
+ d.get("access_count", 0),
222
+ d.get("created_at", datetime.now(UTC).isoformat()),
223
+ ),
224
+ )
225
+ stats["facts_migrated"] += 1
226
+ except sqlite3.Error as exc:
227
+ stats["errors"].append(f"Fact {d.get('id', '?')}: {exc}")
228
+
229
+ return stats
230
+
231
+
232
+ def _migrate_entities(
233
+ v1: sqlite3.Connection,
234
+ new: sqlite3.Connection,
235
+ profile_id: str,
236
+ stats: dict[str, Any],
237
+ ) -> dict[str, Any]:
238
+ """Migrate canonical_entities → entities table."""
239
+ try:
240
+ rows = v1.execute("SELECT * FROM canonical_entities").fetchall()
241
+ except sqlite3.OperationalError:
242
+ return stats
243
+
244
+ for row in rows:
245
+ d = dict(row)
246
+ try:
247
+ new.execute(
248
+ "INSERT OR IGNORE INTO entities "
249
+ "(entity_id, profile_id, canonical_name, entity_type, "
250
+ "first_seen, last_seen, fact_count) "
251
+ "VALUES (?, ?, ?, ?, ?, ?, ?)",
252
+ (
253
+ d.get("entity_id", d.get("id", "")),
254
+ profile_id,
255
+ d.get("canonical_name", d.get("name", "")),
256
+ d.get("entity_type", "unknown"),
257
+ d.get("first_seen", datetime.now(UTC).isoformat()),
258
+ d.get("last_seen", datetime.now(UTC).isoformat()),
259
+ d.get("fact_count", 0),
260
+ ),
261
+ )
262
+ stats["entities_migrated"] += 1
263
+ except sqlite3.Error as exc:
264
+ stats["errors"].append(f"Entity {d.get('id', '?')}: {exc}")
265
+
266
+ return stats
267
+
268
+
269
+ def _migrate_edges(
270
+ v1: sqlite3.Connection,
271
+ new: sqlite3.Connection,
272
+ profile_id: str,
273
+ stats: dict[str, Any],
274
+ ) -> dict[str, Any]:
275
+ """Migrate memory_edges → graph_edges table."""
276
+ try:
277
+ rows = v1.execute("SELECT * FROM memory_edges").fetchall()
278
+ except sqlite3.OperationalError:
279
+ return stats
280
+
281
+ for row in rows:
282
+ d = dict(row)
283
+ try:
284
+ new.execute(
285
+ "INSERT OR IGNORE INTO graph_edges "
286
+ "(edge_id, profile_id, source_id, target_id, edge_type, "
287
+ "weight, created_at) "
288
+ "VALUES (?, ?, ?, ?, ?, ?, ?)",
289
+ (
290
+ d.get("edge_id", d.get("id", "")),
291
+ profile_id,
292
+ d.get("source_id", d.get("source", "")),
293
+ d.get("target_id", d.get("target", "")),
294
+ d.get("edge_type", d.get("relation_type", "entity")),
295
+ d.get("weight", 1.0),
296
+ d.get("created_at", datetime.now(UTC).isoformat()),
297
+ ),
298
+ )
299
+ stats["edges_migrated"] += 1
300
+ except sqlite3.Error as exc:
301
+ stats["errors"].append(f"Edge {d.get('id', '?')}: {exc}")
302
+
303
+ return stats
@@ -0,0 +1,406 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SuperLocalMemory V3 — Data Models.
6
+
7
+ All dataclasses for the memory system. Profile-scoped by design.
8
+ Every model that persists to DB includes profile_id.
9
+
10
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import uuid
16
+ from dataclasses import dataclass, field
17
+ from datetime import UTC, datetime
18
+ from enum import Enum
19
+ from typing import Any
20
+
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # Enums
24
+ # ---------------------------------------------------------------------------
25
+
26
+ class FactType(str, Enum):
27
+ """Memory fact classification — ENGRAM-inspired typed stores."""
28
+
29
+ EPISODIC = "episodic" # Events: who did what when
30
+ SEMANTIC = "semantic" # World knowledge: X is Y
31
+ OPINION = "opinion" # Subjective with confidence
32
+ TEMPORAL = "temporal" # Time-bounded events with intervals
33
+
34
+
35
+ class EdgeType(str, Enum):
36
+ """Knowledge graph edge types."""
37
+
38
+ ENTITY = "entity" # Shared entity link
39
+ TEMPORAL = "temporal" # Chronological ordering
40
+ SEMANTIC = "semantic" # Embedding similarity
41
+ CAUSAL = "causal" # Cause-effect relationship
42
+ CONTRADICTION = "contradiction" # Conflicting facts
43
+ SUPERSEDES = "supersedes" # Newer fact replaces older
44
+
45
+
46
+ class ConsolidationActionType(str, Enum):
47
+ """Mem0-style consolidation actions."""
48
+
49
+ ADD = "add" # New information, store as new fact
50
+ UPDATE = "update" # Refines existing fact
51
+ SUPERSEDE = "supersede" # Contradicts existing fact
52
+ NOOP = "noop" # Duplicate, skip storage
53
+
54
+
55
+ class MemoryLifecycle(str, Enum):
56
+ """Memory lifecycle states — coupled with Langevin dynamics."""
57
+
58
+ ACTIVE = "active" # Frequently accessed, near origin
59
+ WARM = "warm" # Moderate access, mid-radius
60
+ COLD = "cold" # Rarely accessed, near boundary
61
+ ARCHIVED = "archived" # Beyond boundary, deep storage
62
+
63
+
64
+ class SignalType(str, Enum):
65
+ """V2-compatible signal inference types."""
66
+
67
+ FACTUAL = "factual"
68
+ EMOTIONAL = "emotional"
69
+ TEMPORAL = "temporal"
70
+ OPINION = "opinion"
71
+ REQUEST = "request"
72
+ SOCIAL = "social"
73
+
74
+
75
+ class Mode(str, Enum):
76
+ """Operating modes — EU AI Act alignment."""
77
+
78
+ A = "a" # Local Guardian: zero LLM, EU AI Act FULL
79
+ B = "b" # Smart Local: local Ollama LLM, EU AI Act FULL
80
+ C = "c" # Full Power: UNRESTRICTED, best models, 90%+ target
81
+
82
+
83
+ # ---------------------------------------------------------------------------
84
+ # Core Models
85
+ # ---------------------------------------------------------------------------
86
+
87
+ def _new_id() -> str:
88
+ return uuid.uuid4().hex[:16]
89
+
90
+
91
+ def _now() -> str:
92
+ return datetime.now(UTC).isoformat()
93
+
94
+
95
+ @dataclass(frozen=True)
96
+ class Profile:
97
+ """Memory profile — first-class isolation boundary.
98
+
99
+ Every table is scoped by profile_id. Instant switching.
100
+ Ported from V2.8 columnar profile isolation pattern.
101
+ """
102
+
103
+ profile_id: str
104
+ name: str
105
+ description: str = ""
106
+ personality: str = "" # Profile personality description
107
+ mode: Mode = Mode.A # Default operating mode for this profile
108
+ created_at: str = field(default_factory=_now)
109
+ last_used: str | None = None
110
+ config: dict[str, Any] = field(default_factory=dict)
111
+
112
+
113
+ @dataclass
114
+ class MemoryRecord:
115
+ """Primary memory entry — a conversation turn or message.
116
+
117
+ This is the RAW input. Facts are extracted FROM this during encoding.
118
+ """
119
+
120
+ memory_id: str = field(default_factory=_new_id)
121
+ profile_id: str = "default"
122
+ content: str = ""
123
+ session_id: str = ""
124
+ speaker: str = "" # Who said this
125
+ role: str = "" # user / assistant / system
126
+ session_date: str | None = None # Parsed ISO-8601 date
127
+ created_at: str = field(default_factory=_now)
128
+ metadata: dict[str, Any] = field(default_factory=dict)
129
+
130
+
131
+ @dataclass
132
+ class AtomicFact:
133
+ """Structured fact extracted from memory — the PRIMARY retrieval unit.
134
+
135
+ This is what the encoding engine produces. This is what retrieval searches.
136
+ Typed stores (ENGRAM pattern): episodic / semantic / opinion / temporal.
137
+ """
138
+
139
+ fact_id: str = field(default_factory=_new_id)
140
+ memory_id: str = "" # Source memory this was extracted from
141
+ profile_id: str = "default"
142
+ content: str = "" # Atomic fact statement
143
+ fact_type: FactType = FactType.SEMANTIC
144
+
145
+ # Entities
146
+ entities: list[str] = field(default_factory=list)
147
+ canonical_entities: list[str] = field(default_factory=list)
148
+
149
+ # Temporal (3-date model — Mastra pattern)
150
+ observation_date: str | None = None # When the conversation happened
151
+ referenced_date: str | None = None # Date mentioned in content
152
+ interval_start: str | None = None # Event start (for duration events)
153
+ interval_end: str | None = None # Event end
154
+
155
+ # Quality
156
+ confidence: float = 1.0
157
+ importance: float = 0.5 # Priority: 0.0 (low) to 1.0 (critical)
158
+ evidence_count: int = 1 # Incremented on UPDATE consolidation
159
+ access_count: int = 0
160
+
161
+ # Source tracing
162
+ source_turn_ids: list[str] = field(default_factory=list)
163
+ session_id: str = ""
164
+
165
+ # Embeddings (populated by encoding pipeline)
166
+ embedding: list[float] | None = None
167
+ fisher_mean: list[float] | None = None
168
+ fisher_variance: list[float] | None = None
169
+
170
+ # Lifecycle (Langevin-coupled)
171
+ lifecycle: MemoryLifecycle = MemoryLifecycle.ACTIVE
172
+ langevin_position: list[float] | None = None
173
+
174
+ # Emotional (VADER)
175
+ emotional_valence: float = 0.0 # -1.0 negative to +1.0 positive
176
+ emotional_arousal: float = 0.0 # 0.0 calm to 1.0 intense
177
+
178
+ # Signal type (V2 compatible)
179
+ signal_type: SignalType = SignalType.FACTUAL
180
+
181
+ created_at: str = field(default_factory=_now)
182
+
183
+
184
+ @dataclass
185
+ class CanonicalEntity:
186
+ """Resolved canonical entity — the single identity for an entity.
187
+
188
+ Aliases point here. Entity profiles accumulate knowledge about this entity.
189
+ """
190
+
191
+ entity_id: str = field(default_factory=_new_id)
192
+ profile_id: str = "default"
193
+ canonical_name: str = ""
194
+ entity_type: str = "" # person / place / org / concept / event
195
+ first_seen: str = field(default_factory=_now)
196
+ last_seen: str = field(default_factory=_now)
197
+ fact_count: int = 0
198
+
199
+
200
+ @dataclass
201
+ class EntityAlias:
202
+ """Alias mapping to a canonical entity."""
203
+
204
+ alias_id: str = field(default_factory=_new_id)
205
+ entity_id: str = "" # FK to CanonicalEntity
206
+ alias: str = ""
207
+ confidence: float = 1.0
208
+ source: str = "" # How this alias was discovered
209
+
210
+
211
+ @dataclass
212
+ class EntityProfile:
213
+ """Accumulated knowledge about a canonical entity.
214
+
215
+ Built during encoding by ObservationBuilder. Updated on each new fact.
216
+ """
217
+
218
+ profile_entry_id: str = field(default_factory=_new_id)
219
+ entity_id: str = "" # FK to CanonicalEntity
220
+ profile_id: str = "default"
221
+ knowledge_summary: str = "" # Running summary of all facts about entity
222
+ fact_ids: list[str] = field(default_factory=list)
223
+ last_updated: str = field(default_factory=_now)
224
+
225
+
226
+ @dataclass
227
+ class MemoryScene:
228
+ """Clustered group of related facts — EverMemOS MemScene pattern.
229
+
230
+ Scenes provide contextual retrieval: related facts come together.
231
+ """
232
+
233
+ scene_id: str = field(default_factory=_new_id)
234
+ profile_id: str = "default"
235
+ theme: str = "" # Scene description / topic
236
+ fact_ids: list[str] = field(default_factory=list)
237
+ entity_ids: list[str] = field(default_factory=list)
238
+ created_at: str = field(default_factory=_now)
239
+ last_updated: str = field(default_factory=_now)
240
+
241
+
242
+ @dataclass
243
+ class TemporalEvent:
244
+ """Per-entity timeline entry with 3-date model.
245
+
246
+ Enables temporal retrieval: "What happened to Alice in March?"
247
+ """
248
+
249
+ event_id: str = field(default_factory=_new_id)
250
+ profile_id: str = "default"
251
+ entity_id: str = "" # FK to CanonicalEntity
252
+ fact_id: str = "" # FK to AtomicFact
253
+ observation_date: str | None = None
254
+ referenced_date: str | None = None
255
+ interval_start: str | None = None
256
+ interval_end: str | None = None
257
+ description: str = ""
258
+
259
+
260
+ @dataclass
261
+ class GraphEdge:
262
+ """Knowledge graph edge between facts or entities."""
263
+
264
+ edge_id: str = field(default_factory=_new_id)
265
+ profile_id: str = "default"
266
+ source_id: str = "" # Fact ID or Entity ID
267
+ target_id: str = "" # Fact ID or Entity ID
268
+ edge_type: EdgeType = EdgeType.ENTITY
269
+ weight: float = 1.0
270
+ created_at: str = field(default_factory=_now)
271
+
272
+
273
+ @dataclass
274
+ class ConsolidationAction:
275
+ """Log of consolidation decisions (ADD/UPDATE/SUPERSEDE/NOOP)."""
276
+
277
+ action_id: str = field(default_factory=_new_id)
278
+ profile_id: str = "default"
279
+ action_type: ConsolidationActionType = ConsolidationActionType.ADD
280
+ new_fact_id: str = "" # The incoming fact
281
+ existing_fact_id: str = "" # The matched existing fact (if any)
282
+ reason: str = "" # Why this action was chosen
283
+ timestamp: str = field(default_factory=_now)
284
+
285
+
286
+ # ---------------------------------------------------------------------------
287
+ # Trust & Provenance (Ported from V2.8)
288
+ # ---------------------------------------------------------------------------
289
+
290
+ @dataclass
291
+ class TrustScore:
292
+ """Bayesian trust score per source / entity / fact.
293
+
294
+ Updated on access, contradiction, confirmation. Profile-scoped.
295
+ """
296
+
297
+ trust_id: str = field(default_factory=_new_id)
298
+ profile_id: str = "default"
299
+ target_type: str = "" # "entity" / "source" / "fact"
300
+ target_id: str = "" # ID of the entity/source/fact
301
+ trust_score: float = 0.5 # Bayesian: 0.0 = untrusted, 1.0 = fully trusted
302
+ evidence_count: int = 0
303
+ last_updated: str = field(default_factory=_now)
304
+
305
+
306
+ @dataclass
307
+ class ProvenanceRecord:
308
+ """Provenance tracking — who/what created this memory and how."""
309
+
310
+ provenance_id: str = field(default_factory=_new_id)
311
+ profile_id: str = "default"
312
+ fact_id: str = ""
313
+ source_type: str = "" # "conversation" / "import" / "consolidation"
314
+ source_id: str = "" # Session ID or import batch ID
315
+ created_by: str = "" # Agent or user who created this
316
+ timestamp: str = field(default_factory=_now)
317
+
318
+
319
+ # ---------------------------------------------------------------------------
320
+ # Learning & Behavioral (Ported from V2.8)
321
+ # ---------------------------------------------------------------------------
322
+
323
+ @dataclass
324
+ class FeedbackRecord:
325
+ """User feedback on retrieval results — drives adaptive learning."""
326
+
327
+ feedback_id: str = field(default_factory=_new_id)
328
+ profile_id: str = "default"
329
+ query: str = ""
330
+ fact_id: str = ""
331
+ feedback_type: str = "" # "relevant" / "irrelevant" / "partial"
332
+ dwell_time_ms: int = 0
333
+ timestamp: str = field(default_factory=_now)
334
+
335
+
336
+ @dataclass
337
+ class BehavioralPattern:
338
+ """Learned behavioral pattern — query habits, topic preferences."""
339
+
340
+ pattern_id: str = field(default_factory=_new_id)
341
+ profile_id: str = "default"
342
+ pattern_type: str = "" # "query_topic" / "time_of_day" / "entity_pref"
343
+ pattern_key: str = "" # The pattern identifier
344
+ pattern_value: str = "" # Serialized pattern data
345
+ confidence: float = 0.0
346
+ observation_count: int = 0
347
+ last_updated: str = field(default_factory=_now)
348
+
349
+
350
+ @dataclass
351
+ class ActionOutcome:
352
+ """Outcome tracking for learning — did the retrieved facts help?"""
353
+
354
+ outcome_id: str = field(default_factory=_new_id)
355
+ profile_id: str = "default"
356
+ query: str = ""
357
+ fact_ids: list[str] = field(default_factory=list)
358
+ outcome: str = "" # "success" / "partial" / "failure"
359
+ context: dict[str, Any] = field(default_factory=dict)
360
+ timestamp: str = field(default_factory=_now)
361
+
362
+
363
+ # ---------------------------------------------------------------------------
364
+ # Compliance (EU AI Act, GDPR, Lifecycle)
365
+ # ---------------------------------------------------------------------------
366
+
367
+ @dataclass
368
+ class ComplianceAuditEntry:
369
+ """Audit trail for compliance (GDPR right-to-know, EU AI Act)."""
370
+
371
+ audit_id: str = field(default_factory=_new_id)
372
+ profile_id: str = "default"
373
+ action: str = "" # "store" / "retrieve" / "delete" / "export"
374
+ target_type: str = "" # "fact" / "memory" / "profile"
375
+ target_id: str = ""
376
+ details: str = ""
377
+ timestamp: str = field(default_factory=_now)
378
+
379
+
380
+ # ---------------------------------------------------------------------------
381
+ # Retrieval Result (Not persisted — runtime only)
382
+ # ---------------------------------------------------------------------------
383
+
384
+ @dataclass
385
+ class RetrievalResult:
386
+ """A single retrieval result with scores and evidence chain."""
387
+
388
+ fact: AtomicFact
389
+ score: float = 0.0
390
+ channel_scores: dict[str, float] = field(default_factory=dict)
391
+ confidence: float = 0.0
392
+ evidence_chain: list[str] = field(default_factory=list)
393
+ trust_score: float = 0.5
394
+
395
+
396
+ @dataclass
397
+ class RecallResponse:
398
+ """Complete recall response with ranked results and metadata."""
399
+
400
+ query: str = ""
401
+ mode: Mode = Mode.A
402
+ results: list[RetrievalResult] = field(default_factory=list)
403
+ query_type: str = "" # factual / temporal / opinion / multi-hop
404
+ channel_weights: dict[str, float] = field(default_factory=dict)
405
+ total_candidates: int = 0
406
+ retrieval_time_ms: float = 0.0