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,726 @@
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 Schema.
6
+
7
+ SQL DDL for the entire memory system. Zero dead tables: every table
8
+ has both a writer and a reader. Profile-scoped by design.
9
+
10
+ Design principles:
11
+ - 17 tables, each justified by a write path AND a read path
12
+ - profile_id on every row — instant profile switching
13
+ - FTS5 virtual table on atomic_facts for full-text search
14
+ - Foreign keys with CASCADE deletes — no orphans
15
+ - WAL journal mode for concurrent reads
16
+ - Indexes on all hot query paths (entity lookup, temporal range,
17
+ fact_type filter, profile scoping)
18
+
19
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import sqlite3
25
+ from typing import Final
26
+
27
+ # ---------------------------------------------------------------------------
28
+ # Constants
29
+ # ---------------------------------------------------------------------------
30
+
31
+ SCHEMA_VERSION: Final[int] = 1
32
+
33
+ # All table names in creation order (respects FK dependencies).
34
+ # FTS5 virtual tables listed separately — they cannot have FKs.
35
+ _TABLES: Final[tuple[str, ...]] = (
36
+ "schema_version",
37
+ "profiles",
38
+ "memories",
39
+ "atomic_facts",
40
+ "canonical_entities",
41
+ "entity_aliases",
42
+ "entity_profiles",
43
+ "memory_scenes",
44
+ "temporal_events",
45
+ "graph_edges",
46
+ "consolidation_log",
47
+ "trust_scores",
48
+ "provenance",
49
+ "feedback_records",
50
+ "behavioral_patterns",
51
+ "action_outcomes",
52
+ "compliance_audit",
53
+ "bm25_tokens",
54
+ "config",
55
+ )
56
+
57
+ _FTS_TABLES: Final[tuple[str, ...]] = (
58
+ "atomic_facts_fts",
59
+ )
60
+
61
+
62
+ # ---------------------------------------------------------------------------
63
+ # Pragmas
64
+ # ---------------------------------------------------------------------------
65
+
66
+ def _set_pragmas(conn: sqlite3.Connection) -> None:
67
+ """Set SQLite pragmas for performance and integrity."""
68
+ conn.execute("PRAGMA journal_mode = WAL")
69
+ conn.execute("PRAGMA foreign_keys = ON")
70
+ conn.execute("PRAGMA busy_timeout = 5000")
71
+
72
+
73
+ # ---------------------------------------------------------------------------
74
+ # Schema version (must be first — no FK dependencies)
75
+ # ---------------------------------------------------------------------------
76
+
77
+ _SQL_SCHEMA_VERSION: Final[str] = """
78
+ CREATE TABLE IF NOT EXISTS schema_version (
79
+ version INTEGER NOT NULL,
80
+ applied_at TEXT NOT NULL DEFAULT (datetime('now')),
81
+ description TEXT NOT NULL DEFAULT ''
82
+ );
83
+ """
84
+
85
+
86
+ # ---------------------------------------------------------------------------
87
+ # Profiles
88
+ # ---------------------------------------------------------------------------
89
+
90
+ _SQL_PROFILES: Final[str] = """
91
+ CREATE TABLE IF NOT EXISTS profiles (
92
+ profile_id TEXT PRIMARY KEY,
93
+ name TEXT NOT NULL,
94
+ description TEXT NOT NULL DEFAULT '',
95
+ personality TEXT NOT NULL DEFAULT '',
96
+ mode TEXT NOT NULL DEFAULT 'a'
97
+ CHECK (mode IN ('a', 'b', 'c')),
98
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
99
+ last_used TEXT,
100
+ config_json TEXT NOT NULL DEFAULT '{}'
101
+ );
102
+ """
103
+
104
+
105
+ # ---------------------------------------------------------------------------
106
+ # Memories (raw conversation turns)
107
+ # ---------------------------------------------------------------------------
108
+
109
+ _SQL_MEMORIES: Final[str] = """
110
+ CREATE TABLE IF NOT EXISTS memories (
111
+ memory_id TEXT PRIMARY KEY,
112
+ profile_id TEXT NOT NULL DEFAULT 'default',
113
+ content TEXT NOT NULL,
114
+ session_id TEXT NOT NULL DEFAULT '',
115
+ speaker TEXT NOT NULL DEFAULT '',
116
+ role TEXT NOT NULL DEFAULT '',
117
+ session_date TEXT,
118
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
119
+ metadata_json TEXT NOT NULL DEFAULT '{}',
120
+
121
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
122
+ ON DELETE CASCADE
123
+ );
124
+
125
+ CREATE INDEX IF NOT EXISTS idx_memories_profile
126
+ ON memories (profile_id);
127
+ CREATE INDEX IF NOT EXISTS idx_memories_session
128
+ ON memories (profile_id, session_id);
129
+ CREATE INDEX IF NOT EXISTS idx_memories_created
130
+ ON memories (created_at);
131
+ """
132
+
133
+
134
+ # ---------------------------------------------------------------------------
135
+ # Atomic facts — THE primary retrieval unit
136
+ # ---------------------------------------------------------------------------
137
+
138
+ _SQL_ATOMIC_FACTS: Final[str] = """
139
+ CREATE TABLE IF NOT EXISTS atomic_facts (
140
+ fact_id TEXT PRIMARY KEY,
141
+ memory_id TEXT NOT NULL,
142
+ profile_id TEXT NOT NULL DEFAULT 'default',
143
+ content TEXT NOT NULL,
144
+ fact_type TEXT NOT NULL DEFAULT 'semantic'
145
+ CHECK (fact_type IN (
146
+ 'episodic', 'semantic', 'opinion', 'temporal'
147
+ )),
148
+
149
+ -- Entities (JSON arrays)
150
+ entities_json TEXT NOT NULL DEFAULT '[]',
151
+ canonical_entities_json TEXT NOT NULL DEFAULT '[]',
152
+
153
+ -- Temporal (3-date model)
154
+ observation_date TEXT,
155
+ referenced_date TEXT,
156
+ interval_start TEXT,
157
+ interval_end TEXT,
158
+
159
+ -- Quality scores
160
+ confidence REAL NOT NULL DEFAULT 1.0,
161
+ importance REAL NOT NULL DEFAULT 0.5,
162
+ evidence_count INTEGER NOT NULL DEFAULT 1,
163
+ access_count INTEGER NOT NULL DEFAULT 0,
164
+
165
+ -- Source tracing
166
+ source_turn_ids_json TEXT NOT NULL DEFAULT '[]',
167
+ session_id TEXT NOT NULL DEFAULT '',
168
+
169
+ -- Embeddings (JSON arrays — TEXT for simplicity and portability)
170
+ embedding TEXT,
171
+ fisher_mean TEXT,
172
+ fisher_variance TEXT,
173
+
174
+ -- Lifecycle
175
+ lifecycle TEXT NOT NULL DEFAULT 'active'
176
+ CHECK (lifecycle IN (
177
+ 'active', 'warm', 'cold', 'archived'
178
+ )),
179
+ langevin_position TEXT,
180
+
181
+ -- Emotional
182
+ emotional_valence REAL NOT NULL DEFAULT 0.0,
183
+ emotional_arousal REAL NOT NULL DEFAULT 0.0,
184
+
185
+ -- Signal type (V2 compatible)
186
+ signal_type TEXT NOT NULL DEFAULT 'factual',
187
+
188
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
189
+
190
+ FOREIGN KEY (memory_id) REFERENCES memories (memory_id)
191
+ ON DELETE CASCADE,
192
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
193
+ ON DELETE CASCADE
194
+ );
195
+
196
+ CREATE INDEX IF NOT EXISTS idx_facts_profile
197
+ ON atomic_facts (profile_id);
198
+ CREATE INDEX IF NOT EXISTS idx_facts_memory
199
+ ON atomic_facts (memory_id);
200
+ CREATE INDEX IF NOT EXISTS idx_facts_type
201
+ ON atomic_facts (profile_id, fact_type);
202
+ CREATE INDEX IF NOT EXISTS idx_facts_lifecycle
203
+ ON atomic_facts (profile_id, lifecycle);
204
+ CREATE INDEX IF NOT EXISTS idx_facts_session
205
+ ON atomic_facts (profile_id, session_id);
206
+ CREATE INDEX IF NOT EXISTS idx_facts_referenced_date
207
+ ON atomic_facts (profile_id, referenced_date)
208
+ WHERE referenced_date IS NOT NULL;
209
+ CREATE INDEX IF NOT EXISTS idx_facts_interval
210
+ ON atomic_facts (profile_id, interval_start, interval_end)
211
+ WHERE interval_start IS NOT NULL;
212
+ """
213
+
214
+
215
+ # ---------------------------------------------------------------------------
216
+ # FTS5 virtual table on atomic_facts for full-text search
217
+ # ---------------------------------------------------------------------------
218
+
219
+ _SQL_ATOMIC_FACTS_FTS: Final[str] = """
220
+ CREATE VIRTUAL TABLE IF NOT EXISTS atomic_facts_fts
221
+ USING fts5(
222
+ fact_id UNINDEXED,
223
+ content,
224
+ content='atomic_facts',
225
+ content_rowid='rowid'
226
+ );
227
+
228
+ -- Triggers to keep FTS in sync with atomic_facts.
229
+ -- INSERT trigger
230
+ CREATE TRIGGER IF NOT EXISTS atomic_facts_fts_insert
231
+ AFTER INSERT ON atomic_facts
232
+ BEGIN
233
+ INSERT INTO atomic_facts_fts (rowid, fact_id, content)
234
+ VALUES (NEW.rowid, NEW.fact_id, NEW.content);
235
+ END;
236
+
237
+ -- DELETE trigger
238
+ CREATE TRIGGER IF NOT EXISTS atomic_facts_fts_delete
239
+ AFTER DELETE ON atomic_facts
240
+ BEGIN
241
+ INSERT INTO atomic_facts_fts (atomic_facts_fts, rowid, fact_id, content)
242
+ VALUES ('delete', OLD.rowid, OLD.fact_id, OLD.content);
243
+ END;
244
+
245
+ -- UPDATE trigger
246
+ CREATE TRIGGER IF NOT EXISTS atomic_facts_fts_update
247
+ AFTER UPDATE OF content ON atomic_facts
248
+ BEGIN
249
+ INSERT INTO atomic_facts_fts (atomic_facts_fts, rowid, fact_id, content)
250
+ VALUES ('delete', OLD.rowid, OLD.fact_id, OLD.content);
251
+ INSERT INTO atomic_facts_fts (rowid, fact_id, content)
252
+ VALUES (NEW.rowid, NEW.fact_id, NEW.content);
253
+ END;
254
+ """
255
+
256
+
257
+ # ---------------------------------------------------------------------------
258
+ # Canonical entities
259
+ # ---------------------------------------------------------------------------
260
+
261
+ _SQL_CANONICAL_ENTITIES: Final[str] = """
262
+ CREATE TABLE IF NOT EXISTS canonical_entities (
263
+ entity_id TEXT PRIMARY KEY,
264
+ profile_id TEXT NOT NULL DEFAULT 'default',
265
+ canonical_name TEXT NOT NULL,
266
+ entity_type TEXT NOT NULL DEFAULT '',
267
+ first_seen TEXT NOT NULL DEFAULT (datetime('now')),
268
+ last_seen TEXT NOT NULL DEFAULT (datetime('now')),
269
+ fact_count INTEGER NOT NULL DEFAULT 0,
270
+
271
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
272
+ ON DELETE CASCADE
273
+ );
274
+
275
+ CREATE INDEX IF NOT EXISTS idx_entities_profile
276
+ ON canonical_entities (profile_id);
277
+ CREATE INDEX IF NOT EXISTS idx_entities_name_lower
278
+ ON canonical_entities (profile_id, canonical_name COLLATE NOCASE);
279
+ CREATE INDEX IF NOT EXISTS idx_entities_type
280
+ ON canonical_entities (profile_id, entity_type);
281
+ """
282
+
283
+
284
+ # ---------------------------------------------------------------------------
285
+ # Entity aliases
286
+ # ---------------------------------------------------------------------------
287
+
288
+ _SQL_ENTITY_ALIASES: Final[str] = """
289
+ CREATE TABLE IF NOT EXISTS entity_aliases (
290
+ alias_id TEXT PRIMARY KEY,
291
+ entity_id TEXT NOT NULL,
292
+ alias TEXT NOT NULL,
293
+ confidence REAL NOT NULL DEFAULT 1.0,
294
+ source TEXT NOT NULL DEFAULT '',
295
+
296
+ FOREIGN KEY (entity_id) REFERENCES canonical_entities (entity_id)
297
+ ON DELETE CASCADE
298
+ );
299
+
300
+ CREATE INDEX IF NOT EXISTS idx_aliases_entity
301
+ ON entity_aliases (entity_id);
302
+ CREATE INDEX IF NOT EXISTS idx_aliases_lookup
303
+ ON entity_aliases (alias COLLATE NOCASE);
304
+ """
305
+
306
+
307
+ # ---------------------------------------------------------------------------
308
+ # Entity profiles (accumulated knowledge per entity)
309
+ # ---------------------------------------------------------------------------
310
+
311
+ _SQL_ENTITY_PROFILES: Final[str] = """
312
+ CREATE TABLE IF NOT EXISTS entity_profiles (
313
+ profile_entry_id TEXT PRIMARY KEY,
314
+ entity_id TEXT NOT NULL,
315
+ profile_id TEXT NOT NULL DEFAULT 'default',
316
+ knowledge_summary TEXT NOT NULL DEFAULT '',
317
+ fact_ids_json TEXT NOT NULL DEFAULT '[]',
318
+ last_updated TEXT NOT NULL DEFAULT (datetime('now')),
319
+
320
+ FOREIGN KEY (entity_id) REFERENCES canonical_entities (entity_id)
321
+ ON DELETE CASCADE,
322
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
323
+ ON DELETE CASCADE
324
+ );
325
+
326
+ CREATE INDEX IF NOT EXISTS idx_eprofiles_entity
327
+ ON entity_profiles (entity_id);
328
+ CREATE INDEX IF NOT EXISTS idx_eprofiles_profile
329
+ ON entity_profiles (profile_id);
330
+ """
331
+
332
+
333
+ # ---------------------------------------------------------------------------
334
+ # Memory scenes (clustered groups of related facts)
335
+ # ---------------------------------------------------------------------------
336
+
337
+ _SQL_MEMORY_SCENES: Final[str] = """
338
+ CREATE TABLE IF NOT EXISTS memory_scenes (
339
+ scene_id TEXT PRIMARY KEY,
340
+ profile_id TEXT NOT NULL DEFAULT 'default',
341
+ theme TEXT NOT NULL DEFAULT '',
342
+ fact_ids_json TEXT NOT NULL DEFAULT '[]',
343
+ entity_ids_json TEXT NOT NULL DEFAULT '[]',
344
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
345
+ last_updated TEXT NOT NULL DEFAULT (datetime('now')),
346
+
347
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
348
+ ON DELETE CASCADE
349
+ );
350
+
351
+ CREATE INDEX IF NOT EXISTS idx_scenes_profile
352
+ ON memory_scenes (profile_id);
353
+ """
354
+
355
+
356
+ # ---------------------------------------------------------------------------
357
+ # Temporal events (per-entity timeline entries)
358
+ # ---------------------------------------------------------------------------
359
+
360
+ _SQL_TEMPORAL_EVENTS: Final[str] = """
361
+ CREATE TABLE IF NOT EXISTS temporal_events (
362
+ event_id TEXT PRIMARY KEY,
363
+ profile_id TEXT NOT NULL DEFAULT 'default',
364
+ entity_id TEXT NOT NULL,
365
+ fact_id TEXT NOT NULL,
366
+ observation_date TEXT,
367
+ referenced_date TEXT,
368
+ interval_start TEXT,
369
+ interval_end TEXT,
370
+ description TEXT NOT NULL DEFAULT '',
371
+
372
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
373
+ ON DELETE CASCADE,
374
+ FOREIGN KEY (entity_id) REFERENCES canonical_entities (entity_id)
375
+ ON DELETE CASCADE,
376
+ FOREIGN KEY (fact_id) REFERENCES atomic_facts (fact_id)
377
+ ON DELETE CASCADE
378
+ );
379
+
380
+ CREATE INDEX IF NOT EXISTS idx_tevents_profile
381
+ ON temporal_events (profile_id);
382
+ CREATE INDEX IF NOT EXISTS idx_tevents_entity
383
+ ON temporal_events (profile_id, entity_id);
384
+ CREATE INDEX IF NOT EXISTS idx_tevents_date_range
385
+ ON temporal_events (profile_id, referenced_date)
386
+ WHERE referenced_date IS NOT NULL;
387
+ """
388
+
389
+
390
+ # ---------------------------------------------------------------------------
391
+ # Graph edges (knowledge graph between facts/entities)
392
+ # ---------------------------------------------------------------------------
393
+
394
+ _SQL_GRAPH_EDGES: Final[str] = """
395
+ CREATE TABLE IF NOT EXISTS graph_edges (
396
+ edge_id TEXT PRIMARY KEY,
397
+ profile_id TEXT NOT NULL DEFAULT 'default',
398
+ source_id TEXT NOT NULL,
399
+ target_id TEXT NOT NULL,
400
+ edge_type TEXT NOT NULL DEFAULT 'entity'
401
+ CHECK (edge_type IN (
402
+ 'entity', 'temporal', 'semantic',
403
+ 'causal', 'contradiction', 'supersedes'
404
+ )),
405
+ weight REAL NOT NULL DEFAULT 1.0,
406
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
407
+
408
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
409
+ ON DELETE CASCADE
410
+ );
411
+
412
+ CREATE INDEX IF NOT EXISTS idx_edges_profile
413
+ ON graph_edges (profile_id);
414
+ CREATE INDEX IF NOT EXISTS idx_edges_source
415
+ ON graph_edges (profile_id, source_id);
416
+ CREATE INDEX IF NOT EXISTS idx_edges_target
417
+ ON graph_edges (profile_id, target_id);
418
+ CREATE INDEX IF NOT EXISTS idx_edges_type
419
+ ON graph_edges (profile_id, edge_type);
420
+ """
421
+
422
+
423
+ # ---------------------------------------------------------------------------
424
+ # Consolidation log (ADD / UPDATE / SUPERSEDE / NOOP decisions)
425
+ # ---------------------------------------------------------------------------
426
+
427
+ _SQL_CONSOLIDATION_LOG: Final[str] = """
428
+ CREATE TABLE IF NOT EXISTS consolidation_log (
429
+ action_id TEXT PRIMARY KEY,
430
+ profile_id TEXT NOT NULL DEFAULT 'default',
431
+ action_type TEXT NOT NULL DEFAULT 'add'
432
+ CHECK (action_type IN (
433
+ 'add', 'update', 'supersede', 'noop'
434
+ )),
435
+ new_fact_id TEXT NOT NULL DEFAULT '',
436
+ existing_fact_id TEXT NOT NULL DEFAULT '',
437
+ reason TEXT NOT NULL DEFAULT '',
438
+ timestamp TEXT NOT NULL DEFAULT (datetime('now')),
439
+
440
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
441
+ ON DELETE CASCADE
442
+ );
443
+
444
+ CREATE INDEX IF NOT EXISTS idx_conslog_profile
445
+ ON consolidation_log (profile_id);
446
+ CREATE INDEX IF NOT EXISTS idx_conslog_new_fact
447
+ ON consolidation_log (new_fact_id);
448
+ """
449
+
450
+
451
+ # ---------------------------------------------------------------------------
452
+ # Trust scores (Bayesian per source / entity / fact)
453
+ # ---------------------------------------------------------------------------
454
+
455
+ _SQL_TRUST_SCORES: Final[str] = """
456
+ CREATE TABLE IF NOT EXISTS trust_scores (
457
+ trust_id TEXT PRIMARY KEY,
458
+ profile_id TEXT NOT NULL DEFAULT 'default',
459
+ target_type TEXT NOT NULL DEFAULT '',
460
+ target_id TEXT NOT NULL DEFAULT '',
461
+ trust_score REAL NOT NULL DEFAULT 0.5,
462
+ evidence_count INTEGER NOT NULL DEFAULT 0,
463
+ last_updated TEXT NOT NULL DEFAULT (datetime('now')),
464
+
465
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
466
+ ON DELETE CASCADE
467
+ );
468
+
469
+ CREATE INDEX IF NOT EXISTS idx_trust_profile
470
+ ON trust_scores (profile_id);
471
+ CREATE INDEX IF NOT EXISTS idx_trust_target
472
+ ON trust_scores (profile_id, target_type, target_id);
473
+ """
474
+
475
+
476
+ # ---------------------------------------------------------------------------
477
+ # Provenance (who/what created this memory and how)
478
+ # ---------------------------------------------------------------------------
479
+
480
+ _SQL_PROVENANCE: Final[str] = """
481
+ CREATE TABLE IF NOT EXISTS provenance (
482
+ provenance_id TEXT PRIMARY KEY,
483
+ profile_id TEXT NOT NULL DEFAULT 'default',
484
+ fact_id TEXT NOT NULL,
485
+ source_type TEXT NOT NULL DEFAULT '',
486
+ source_id TEXT NOT NULL DEFAULT '',
487
+ created_by TEXT NOT NULL DEFAULT '',
488
+ timestamp TEXT NOT NULL DEFAULT (datetime('now')),
489
+
490
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
491
+ ON DELETE CASCADE,
492
+ FOREIGN KEY (fact_id) REFERENCES atomic_facts (fact_id)
493
+ ON DELETE CASCADE
494
+ );
495
+
496
+ CREATE INDEX IF NOT EXISTS idx_prov_profile
497
+ ON provenance (profile_id);
498
+ CREATE INDEX IF NOT EXISTS idx_prov_fact
499
+ ON provenance (fact_id);
500
+ """
501
+
502
+
503
+ # ---------------------------------------------------------------------------
504
+ # Feedback records (user feedback on retrieval results)
505
+ # ---------------------------------------------------------------------------
506
+
507
+ _SQL_FEEDBACK_RECORDS: Final[str] = """
508
+ CREATE TABLE IF NOT EXISTS feedback_records (
509
+ feedback_id TEXT PRIMARY KEY,
510
+ profile_id TEXT NOT NULL DEFAULT 'default',
511
+ query TEXT NOT NULL DEFAULT '',
512
+ fact_id TEXT NOT NULL,
513
+ feedback_type TEXT NOT NULL DEFAULT '',
514
+ dwell_time_ms INTEGER NOT NULL DEFAULT 0,
515
+ timestamp TEXT NOT NULL DEFAULT (datetime('now')),
516
+
517
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
518
+ ON DELETE CASCADE,
519
+ FOREIGN KEY (fact_id) REFERENCES atomic_facts (fact_id)
520
+ ON DELETE CASCADE
521
+ );
522
+
523
+ CREATE INDEX IF NOT EXISTS idx_feedback_profile
524
+ ON feedback_records (profile_id);
525
+ CREATE INDEX IF NOT EXISTS idx_feedback_fact
526
+ ON feedback_records (fact_id);
527
+ """
528
+
529
+
530
+ # ---------------------------------------------------------------------------
531
+ # Behavioral patterns (learned query habits / topic prefs)
532
+ # ---------------------------------------------------------------------------
533
+
534
+ _SQL_BEHAVIORAL_PATTERNS: Final[str] = """
535
+ CREATE TABLE IF NOT EXISTS behavioral_patterns (
536
+ pattern_id TEXT PRIMARY KEY,
537
+ profile_id TEXT NOT NULL DEFAULT 'default',
538
+ pattern_type TEXT NOT NULL DEFAULT '',
539
+ pattern_key TEXT NOT NULL DEFAULT '',
540
+ pattern_value TEXT NOT NULL DEFAULT '',
541
+ confidence REAL NOT NULL DEFAULT 0.0,
542
+ observation_count INTEGER NOT NULL DEFAULT 0,
543
+ last_updated TEXT NOT NULL DEFAULT (datetime('now')),
544
+
545
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
546
+ ON DELETE CASCADE
547
+ );
548
+
549
+ CREATE INDEX IF NOT EXISTS idx_bpatterns_profile
550
+ ON behavioral_patterns (profile_id);
551
+ CREATE INDEX IF NOT EXISTS idx_bpatterns_type
552
+ ON behavioral_patterns (profile_id, pattern_type);
553
+ """
554
+
555
+
556
+ # ---------------------------------------------------------------------------
557
+ # Action outcomes (did the retrieved facts help?)
558
+ # ---------------------------------------------------------------------------
559
+
560
+ _SQL_ACTION_OUTCOMES: Final[str] = """
561
+ CREATE TABLE IF NOT EXISTS action_outcomes (
562
+ outcome_id TEXT PRIMARY KEY,
563
+ profile_id TEXT NOT NULL DEFAULT 'default',
564
+ query TEXT NOT NULL DEFAULT '',
565
+ fact_ids_json TEXT NOT NULL DEFAULT '[]',
566
+ outcome TEXT NOT NULL DEFAULT '',
567
+ context_json TEXT NOT NULL DEFAULT '{}',
568
+ timestamp TEXT NOT NULL DEFAULT (datetime('now')),
569
+
570
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
571
+ ON DELETE CASCADE
572
+ );
573
+
574
+ CREATE INDEX IF NOT EXISTS idx_outcomes_profile
575
+ ON action_outcomes (profile_id);
576
+ """
577
+
578
+
579
+ # ---------------------------------------------------------------------------
580
+ # Compliance audit (GDPR, EU AI Act trail)
581
+ # ---------------------------------------------------------------------------
582
+
583
+ _SQL_COMPLIANCE_AUDIT: Final[str] = """
584
+ CREATE TABLE IF NOT EXISTS compliance_audit (
585
+ audit_id TEXT PRIMARY KEY,
586
+ profile_id TEXT NOT NULL DEFAULT 'default',
587
+ action TEXT NOT NULL DEFAULT '',
588
+ target_type TEXT NOT NULL DEFAULT '',
589
+ target_id TEXT NOT NULL DEFAULT '',
590
+ details TEXT NOT NULL DEFAULT '',
591
+ timestamp TEXT NOT NULL DEFAULT (datetime('now')),
592
+
593
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
594
+ ON DELETE CASCADE
595
+ );
596
+
597
+ CREATE INDEX IF NOT EXISTS idx_audit_profile
598
+ ON compliance_audit (profile_id);
599
+ CREATE INDEX IF NOT EXISTS idx_audit_action
600
+ ON compliance_audit (profile_id, action);
601
+ CREATE INDEX IF NOT EXISTS idx_audit_target
602
+ ON compliance_audit (profile_id, target_type, target_id);
603
+ """
604
+
605
+
606
+ # ---------------------------------------------------------------------------
607
+ # BM25 Token Persistence
608
+ # ---------------------------------------------------------------------------
609
+
610
+ _SQL_BM25_TOKENS: Final[str] = """
611
+ CREATE TABLE IF NOT EXISTS bm25_tokens (
612
+ fact_id TEXT NOT NULL,
613
+ profile_id TEXT NOT NULL DEFAULT 'default',
614
+ tokens TEXT NOT NULL DEFAULT '[]',
615
+
616
+ PRIMARY KEY (fact_id, profile_id),
617
+ FOREIGN KEY (profile_id) REFERENCES profiles (profile_id)
618
+ ON DELETE CASCADE
619
+ );
620
+ """
621
+
622
+ # ---------------------------------------------------------------------------
623
+ # Key-Value Config Store
624
+ # ---------------------------------------------------------------------------
625
+
626
+ _SQL_CONFIG: Final[str] = """
627
+ CREATE TABLE IF NOT EXISTS config (
628
+ key TEXT PRIMARY KEY,
629
+ value TEXT NOT NULL DEFAULT '',
630
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
631
+ );
632
+ """
633
+
634
+ # ---------------------------------------------------------------------------
635
+ # Ordered DDL list (tables before FTS, respects FK order)
636
+ # ---------------------------------------------------------------------------
637
+
638
+ _DDL_ORDERED: Final[tuple[str, ...]] = (
639
+ _SQL_SCHEMA_VERSION,
640
+ _SQL_PROFILES,
641
+ _SQL_MEMORIES,
642
+ _SQL_ATOMIC_FACTS,
643
+ _SQL_CANONICAL_ENTITIES,
644
+ _SQL_ENTITY_ALIASES,
645
+ _SQL_ENTITY_PROFILES,
646
+ _SQL_MEMORY_SCENES,
647
+ _SQL_TEMPORAL_EVENTS,
648
+ _SQL_GRAPH_EDGES,
649
+ _SQL_CONSOLIDATION_LOG,
650
+ _SQL_TRUST_SCORES,
651
+ _SQL_PROVENANCE,
652
+ _SQL_FEEDBACK_RECORDS,
653
+ _SQL_BEHAVIORAL_PATTERNS,
654
+ _SQL_ACTION_OUTCOMES,
655
+ _SQL_COMPLIANCE_AUDIT,
656
+ _SQL_BM25_TOKENS,
657
+ _SQL_CONFIG,
658
+ # FTS5 must come after atomic_facts (content table)
659
+ _SQL_ATOMIC_FACTS_FTS,
660
+ )
661
+
662
+
663
+ # ---------------------------------------------------------------------------
664
+ # Public API
665
+ # ---------------------------------------------------------------------------
666
+
667
+ def create_all_tables(conn: sqlite3.Connection) -> None:
668
+ """Create every table, index, trigger, and FTS virtual table.
669
+
670
+ Safe to call repeatedly — all statements use IF NOT EXISTS.
671
+ Inserts the initial schema_version row on first run.
672
+
673
+ Args:
674
+ conn: An open SQLite connection. Caller manages commit.
675
+ """
676
+ _set_pragmas(conn)
677
+
678
+ for ddl in _DDL_ORDERED:
679
+ conn.executescript(ddl)
680
+
681
+ # Seed schema version on first run.
682
+ existing = conn.execute(
683
+ "SELECT COUNT(*) AS n FROM schema_version"
684
+ ).fetchone()
685
+ if existing[0] == 0:
686
+ conn.execute(
687
+ "INSERT INTO schema_version (version, description) VALUES (?, ?)",
688
+ (SCHEMA_VERSION, "Initial schema — zero dead tables"),
689
+ )
690
+
691
+ # Ensure the 'default' profile exists.
692
+ conn.execute(
693
+ "INSERT OR IGNORE INTO profiles (profile_id, name) VALUES (?, ?)",
694
+ ("default", "Default Profile"),
695
+ )
696
+
697
+
698
+ def drop_all_tables(conn: sqlite3.Connection) -> None:
699
+ """Drop every table and FTS virtual table. For testing only.
700
+
701
+ Args:
702
+ conn: An open SQLite connection. Caller manages commit.
703
+ """
704
+ # FTS + triggers first (depend on atomic_facts).
705
+ for fts in _FTS_TABLES:
706
+ conn.execute(f"DROP TABLE IF EXISTS {fts}")
707
+ for trigger in (
708
+ "atomic_facts_fts_insert",
709
+ "atomic_facts_fts_delete",
710
+ "atomic_facts_fts_update",
711
+ ):
712
+ conn.execute(f"DROP TRIGGER IF EXISTS {trigger}")
713
+
714
+ # Drop regular tables in reverse FK order.
715
+ for table in reversed(_TABLES):
716
+ conn.execute(f"DROP TABLE IF EXISTS {table}")
717
+
718
+
719
+ def get_table_names() -> tuple[str, ...]:
720
+ """Return all regular table names (excludes FTS virtual tables)."""
721
+ return _TABLES
722
+
723
+
724
+ def get_fts_table_names() -> tuple[str, ...]:
725
+ """Return all FTS virtual table names."""
726
+ return _FTS_TABLES