superlocalmemory 3.4.5 → 3.4.8

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 (232) hide show
  1. package/ide/hooks/tool-event-hook.sh +46 -0
  2. package/package.json +1 -1
  3. package/pyproject.toml +1 -1
  4. package/src/superlocalmemory/attribution/mathematical_dna.py +1 -1
  5. package/src/superlocalmemory/attribution/signer.py +1 -1
  6. package/src/superlocalmemory/attribution/watermark.py +1 -1
  7. package/src/superlocalmemory/cli/__init__.py +1 -1
  8. package/src/superlocalmemory/cli/commands.py +9 -1
  9. package/src/superlocalmemory/cli/daemon.py +57 -27
  10. package/src/superlocalmemory/cli/ingest_cmd.py +261 -0
  11. package/src/superlocalmemory/cli/json_output.py +1 -1
  12. package/src/superlocalmemory/cli/main.py +21 -1
  13. package/src/superlocalmemory/cli/migrate_cmd.py +1 -1
  14. package/src/superlocalmemory/cli/pending_store.py +1 -1
  15. package/src/superlocalmemory/cli/post_install.py +1 -1
  16. package/src/superlocalmemory/cli/service_installer.py +1 -1
  17. package/src/superlocalmemory/cli/setup_wizard.py +1 -1
  18. package/src/superlocalmemory/code_graph/__init__.py +1 -1
  19. package/src/superlocalmemory/code_graph/blast_radius.py +1 -1
  20. package/src/superlocalmemory/code_graph/bridge/__init__.py +1 -1
  21. package/src/superlocalmemory/code_graph/bridge/entity_resolver.py +1 -1
  22. package/src/superlocalmemory/code_graph/bridge/event_listeners.py +1 -1
  23. package/src/superlocalmemory/code_graph/bridge/fact_enricher.py +1 -1
  24. package/src/superlocalmemory/code_graph/bridge/hebbian_linker.py +1 -1
  25. package/src/superlocalmemory/code_graph/bridge/temporal_checker.py +1 -1
  26. package/src/superlocalmemory/code_graph/changes.py +1 -1
  27. package/src/superlocalmemory/code_graph/communities.py +1 -1
  28. package/src/superlocalmemory/code_graph/config.py +1 -1
  29. package/src/superlocalmemory/code_graph/database.py +1 -1
  30. package/src/superlocalmemory/code_graph/extractors/__init__.py +1 -1
  31. package/src/superlocalmemory/code_graph/extractors/python.py +1 -1
  32. package/src/superlocalmemory/code_graph/extractors/typescript.py +1 -1
  33. package/src/superlocalmemory/code_graph/flows.py +1 -1
  34. package/src/superlocalmemory/code_graph/git_hooks.py +1 -1
  35. package/src/superlocalmemory/code_graph/graph_engine.py +1 -1
  36. package/src/superlocalmemory/code_graph/graph_store.py +1 -1
  37. package/src/superlocalmemory/code_graph/incremental.py +1 -1
  38. package/src/superlocalmemory/code_graph/models.py +1 -1
  39. package/src/superlocalmemory/code_graph/parser.py +1 -1
  40. package/src/superlocalmemory/code_graph/resolver.py +1 -1
  41. package/src/superlocalmemory/code_graph/search.py +1 -1
  42. package/src/superlocalmemory/code_graph/service.py +1 -1
  43. package/src/superlocalmemory/code_graph/watcher.py +1 -1
  44. package/src/superlocalmemory/compliance/abac.py +1 -1
  45. package/src/superlocalmemory/compliance/audit.py +1 -1
  46. package/src/superlocalmemory/compliance/eu_ai_act.py +1 -1
  47. package/src/superlocalmemory/compliance/gdpr.py +1 -1
  48. package/src/superlocalmemory/compliance/lifecycle.py +1 -1
  49. package/src/superlocalmemory/compliance/retention.py +1 -1
  50. package/src/superlocalmemory/compliance/scheduler.py +1 -1
  51. package/src/superlocalmemory/core/config.py +1 -1
  52. package/src/superlocalmemory/core/consolidation_engine.py +52 -1
  53. package/src/superlocalmemory/core/embedding_worker.py +1 -1
  54. package/src/superlocalmemory/core/embeddings.py +1 -1
  55. package/src/superlocalmemory/core/engine.py +17 -1
  56. package/src/superlocalmemory/core/engine_wiring.py +21 -1
  57. package/src/superlocalmemory/core/graph_analyzer.py +15 -1
  58. package/src/superlocalmemory/core/health_monitor.py +1 -1
  59. package/src/superlocalmemory/core/hooks.py +1 -1
  60. package/src/superlocalmemory/core/maintenance.py +1 -1
  61. package/src/superlocalmemory/core/maintenance_scheduler.py +1 -1
  62. package/src/superlocalmemory/core/modes.py +1 -1
  63. package/src/superlocalmemory/core/ollama_embedder.py +1 -1
  64. package/src/superlocalmemory/core/profiles.py +1 -1
  65. package/src/superlocalmemory/core/recall_pipeline.py +16 -3
  66. package/src/superlocalmemory/core/recall_worker.py +1 -1
  67. package/src/superlocalmemory/core/registry.py +1 -1
  68. package/src/superlocalmemory/core/reranker_worker.py +1 -1
  69. package/src/superlocalmemory/core/store_pipeline.py +1 -1
  70. package/src/superlocalmemory/core/summarizer.py +1 -1
  71. package/src/superlocalmemory/core/worker_pool.py +1 -1
  72. package/src/superlocalmemory/dynamics/activation_guided_quantization.py +1 -1
  73. package/src/superlocalmemory/dynamics/eap_scheduler.py +1 -1
  74. package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +1 -1
  75. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +1 -1
  76. package/src/superlocalmemory/encoding/auto_linker.py +1 -1
  77. package/src/superlocalmemory/encoding/cognitive_consolidator.py +1 -1
  78. package/src/superlocalmemory/encoding/consolidator.py +1 -1
  79. package/src/superlocalmemory/encoding/context_generator.py +1 -1
  80. package/src/superlocalmemory/encoding/emotional.py +1 -1
  81. package/src/superlocalmemory/encoding/entity_resolver.py +45 -6
  82. package/src/superlocalmemory/encoding/entropy_gate.py +1 -1
  83. package/src/superlocalmemory/encoding/fact_extractor.py +1 -1
  84. package/src/superlocalmemory/encoding/foresight.py +1 -1
  85. package/src/superlocalmemory/encoding/graph_builder.py +1 -1
  86. package/src/superlocalmemory/encoding/observation_builder.py +1 -1
  87. package/src/superlocalmemory/encoding/scene_builder.py +1 -1
  88. package/src/superlocalmemory/encoding/signal_inference.py +1 -1
  89. package/src/superlocalmemory/encoding/temporal_parser.py +1 -1
  90. package/src/superlocalmemory/encoding/temporal_validator.py +1 -1
  91. package/src/superlocalmemory/encoding/type_router.py +1 -1
  92. package/src/superlocalmemory/hooks/__init__.py +1 -1
  93. package/src/superlocalmemory/hooks/auto_capture.py +1 -1
  94. package/src/superlocalmemory/hooks/auto_invoker.py +1 -1
  95. package/src/superlocalmemory/hooks/auto_parameterize.py +1 -1
  96. package/src/superlocalmemory/hooks/auto_recall.py +1 -1
  97. package/src/superlocalmemory/hooks/claude_code_hooks.py +1 -1
  98. package/src/superlocalmemory/hooks/hook_handlers.py +1 -1
  99. package/src/superlocalmemory/hooks/ide_connector.py +1 -1
  100. package/src/superlocalmemory/hooks/rules_engine.py +1 -1
  101. package/src/superlocalmemory/infra/__init__.py +1 -1
  102. package/src/superlocalmemory/infra/auth_middleware.py +1 -1
  103. package/src/superlocalmemory/infra/backup.py +1 -1
  104. package/src/superlocalmemory/infra/cache_manager.py +1 -1
  105. package/src/superlocalmemory/infra/event_bus.py +1 -1
  106. package/src/superlocalmemory/infra/heartbeat_monitor.py +1 -1
  107. package/src/superlocalmemory/infra/pid_manager.py +1 -1
  108. package/src/superlocalmemory/infra/process_reaper.py +1 -1
  109. package/src/superlocalmemory/infra/rate_limiter.py +1 -1
  110. package/src/superlocalmemory/infra/webhook_dispatcher.py +1 -1
  111. package/src/superlocalmemory/ingestion/__init__.py +1 -1
  112. package/src/superlocalmemory/ingestion/adapter_manager.py +1 -1
  113. package/src/superlocalmemory/ingestion/base_adapter.py +1 -1
  114. package/src/superlocalmemory/ingestion/calendar_adapter.py +1 -1
  115. package/src/superlocalmemory/ingestion/credentials.py +1 -1
  116. package/src/superlocalmemory/ingestion/gmail_adapter.py +1 -1
  117. package/src/superlocalmemory/ingestion/parsers.py +1 -1
  118. package/src/superlocalmemory/ingestion/transcript_adapter.py +1 -1
  119. package/src/superlocalmemory/learning/adaptive.py +1 -1
  120. package/src/superlocalmemory/learning/assertion_miner.py +403 -0
  121. package/src/superlocalmemory/learning/behavioral.py +1 -1
  122. package/src/superlocalmemory/learning/behavioral_listener.py +1 -1
  123. package/src/superlocalmemory/learning/bootstrap.py +1 -1
  124. package/src/superlocalmemory/learning/consolidation_quantization_worker.py +1 -1
  125. package/src/superlocalmemory/learning/consolidation_worker.py +25 -9
  126. package/src/superlocalmemory/learning/cross_project.py +1 -1
  127. package/src/superlocalmemory/learning/database.py +1 -1
  128. package/src/superlocalmemory/learning/engagement.py +2 -3
  129. package/src/superlocalmemory/learning/entity_compiler.py +1 -1
  130. package/src/superlocalmemory/learning/features.py +1 -1
  131. package/src/superlocalmemory/learning/forgetting_scheduler.py +1 -1
  132. package/src/superlocalmemory/learning/outcomes.py +1 -1
  133. package/src/superlocalmemory/learning/project_context.py +1 -1
  134. package/src/superlocalmemory/learning/quantization_scheduler.py +1 -1
  135. package/src/superlocalmemory/learning/ranker.py +1 -1
  136. package/src/superlocalmemory/learning/signals.py +1 -1
  137. package/src/superlocalmemory/learning/workflows.py +1 -1
  138. package/src/superlocalmemory/llm/backbone.py +1 -1
  139. package/src/superlocalmemory/math/ebbinghaus.py +1 -1
  140. package/src/superlocalmemory/math/fisher.py +1 -1
  141. package/src/superlocalmemory/math/fisher_quantized.py +1 -1
  142. package/src/superlocalmemory/math/hopfield.py +1 -1
  143. package/src/superlocalmemory/math/langevin.py +1 -1
  144. package/src/superlocalmemory/math/polar_quant.py +1 -1
  145. package/src/superlocalmemory/math/qjl.py +1 -1
  146. package/src/superlocalmemory/math/sheaf.py +1 -1
  147. package/src/superlocalmemory/math/turbo_quant.py +1 -1
  148. package/src/superlocalmemory/mcp/resources.py +1 -1
  149. package/src/superlocalmemory/mcp/server.py +17 -2
  150. package/src/superlocalmemory/mcp/shared.py +1 -1
  151. package/src/superlocalmemory/mcp/tools.py +1 -1
  152. package/src/superlocalmemory/mcp/tools_active.py +1 -1
  153. package/src/superlocalmemory/mcp/tools_code_graph.py +1 -1
  154. package/src/superlocalmemory/mcp/tools_core.py +1 -1
  155. package/src/superlocalmemory/mcp/tools_learning.py +221 -0
  156. package/src/superlocalmemory/mcp/tools_mesh.py +55 -12
  157. package/src/superlocalmemory/mcp/tools_v28.py +23 -1
  158. package/src/superlocalmemory/mcp/tools_v3.py +1 -1
  159. package/src/superlocalmemory/mcp/tools_v33.py +1 -1
  160. package/src/superlocalmemory/mesh/__init__.py +1 -1
  161. package/src/superlocalmemory/mesh/broker.py +194 -38
  162. package/src/superlocalmemory/parameterization/__init__.py +1 -1
  163. package/src/superlocalmemory/parameterization/pattern_extractor.py +35 -1
  164. package/src/superlocalmemory/parameterization/pii_filter.py +1 -1
  165. package/src/superlocalmemory/parameterization/prompt_injector.py +3 -2
  166. package/src/superlocalmemory/parameterization/prompt_lifecycle.py +1 -1
  167. package/src/superlocalmemory/parameterization/soft_prompt_generator.py +7 -1
  168. package/src/superlocalmemory/retrieval/agentic.py +1 -1
  169. package/src/superlocalmemory/retrieval/ann_index.py +1 -1
  170. package/src/superlocalmemory/retrieval/bm25_channel.py +1 -1
  171. package/src/superlocalmemory/retrieval/bridge_discovery.py +1 -1
  172. package/src/superlocalmemory/retrieval/channel_registry.py +1 -1
  173. package/src/superlocalmemory/retrieval/engine.py +1 -1
  174. package/src/superlocalmemory/retrieval/entity_channel.py +1 -1
  175. package/src/superlocalmemory/retrieval/forgetting_filter.py +1 -1
  176. package/src/superlocalmemory/retrieval/fusion.py +1 -1
  177. package/src/superlocalmemory/retrieval/hopfield_channel.py +1 -1
  178. package/src/superlocalmemory/retrieval/profile_channel.py +1 -1
  179. package/src/superlocalmemory/retrieval/quantization_aware_search.py +1 -1
  180. package/src/superlocalmemory/retrieval/reranker.py +1 -1
  181. package/src/superlocalmemory/retrieval/semantic_channel.py +1 -1
  182. package/src/superlocalmemory/retrieval/spreading_activation.py +1 -1
  183. package/src/superlocalmemory/retrieval/strategy.py +1 -1
  184. package/src/superlocalmemory/retrieval/temporal_channel.py +1 -1
  185. package/src/superlocalmemory/retrieval/vector_store.py +1 -1
  186. package/src/superlocalmemory/server/api.py +1 -1
  187. package/src/superlocalmemory/server/routes/__init__.py +1 -1
  188. package/src/superlocalmemory/server/routes/adapters.py +1 -1
  189. package/src/superlocalmemory/server/routes/agents.py +2 -2
  190. package/src/superlocalmemory/server/routes/backup.py +2 -2
  191. package/src/superlocalmemory/server/routes/behavioral.py +129 -2
  192. package/src/superlocalmemory/server/routes/compliance.py +2 -2
  193. package/src/superlocalmemory/server/routes/data_io.py +2 -2
  194. package/src/superlocalmemory/server/routes/entity.py +1 -1
  195. package/src/superlocalmemory/server/routes/events.py +2 -2
  196. package/src/superlocalmemory/server/routes/helpers.py +2 -2
  197. package/src/superlocalmemory/server/routes/ingest.py +1 -1
  198. package/src/superlocalmemory/server/routes/learning.py +22 -5
  199. package/src/superlocalmemory/server/routes/lifecycle.py +2 -2
  200. package/src/superlocalmemory/server/routes/memories.py +2 -2
  201. package/src/superlocalmemory/server/routes/mesh.py +25 -7
  202. package/src/superlocalmemory/server/routes/profiles.py +2 -2
  203. package/src/superlocalmemory/server/routes/stats.py +26 -7
  204. package/src/superlocalmemory/server/routes/v3_api.py +1 -1
  205. package/src/superlocalmemory/server/routes/ws.py +2 -2
  206. package/src/superlocalmemory/server/ui.py +1 -1
  207. package/src/superlocalmemory/server/unified_daemon.py +42 -1
  208. package/src/superlocalmemory/storage/access_control.py +1 -1
  209. package/src/superlocalmemory/storage/access_log.py +1 -1
  210. package/src/superlocalmemory/storage/database.py +1 -1
  211. package/src/superlocalmemory/storage/embedding_migrator.py +1 -1
  212. package/src/superlocalmemory/storage/migration_v33.py +1 -1
  213. package/src/superlocalmemory/storage/migrations.py +1 -1
  214. package/src/superlocalmemory/storage/models.py +1 -1
  215. package/src/superlocalmemory/storage/quantized_store.py +1 -1
  216. package/src/superlocalmemory/storage/schema.py +1 -1
  217. package/src/superlocalmemory/storage/schema_code_graph.py +1 -1
  218. package/src/superlocalmemory/storage/schema_v32.py +1 -1
  219. package/src/superlocalmemory/storage/schema_v343.py +75 -1
  220. package/src/superlocalmemory/storage/schema_v347.py +136 -0
  221. package/src/superlocalmemory/storage/v2_migrator.py +1 -1
  222. package/src/superlocalmemory/trust/gate.py +1 -1
  223. package/src/superlocalmemory/trust/provenance.py +1 -1
  224. package/src/superlocalmemory/trust/scorer.py +1 -1
  225. package/src/superlocalmemory/trust/signals.py +1 -1
  226. package/src/superlocalmemory/ui/js/behavioral.js +174 -3
  227. package/src/superlocalmemory.egg-info/PKG-INFO +0 -601
  228. package/src/superlocalmemory.egg-info/SOURCES.txt +0 -313
  229. package/src/superlocalmemory.egg-info/dependency_links.txt +0 -1
  230. package/src/superlocalmemory.egg-info/entry_points.txt +0 -2
  231. package/src/superlocalmemory.egg-info/requires.txt +0 -55
  232. package/src/superlocalmemory.egg-info/top_level.txt +0 -1
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3.4.3 "The Unified Brain" — Schema Extensions.
@@ -151,6 +151,80 @@ CREATE TABLE IF NOT EXISTS schema_version (
151
151
  # Migration runner
152
152
  # ---------------------------------------------------------------------------
153
153
 
154
+ # ---------------------------------------------------------------------------
155
+ # DDL — v3.4.6: Mesh Connected Brain (broadcast, project routing, offline queue)
156
+ # ---------------------------------------------------------------------------
157
+
158
+ _MESH_V346_ALTERS = [
159
+ "ALTER TABLE mesh_peers ADD COLUMN project_path TEXT DEFAULT ''",
160
+ "ALTER TABLE mesh_peers ADD COLUMN agent_type TEXT DEFAULT 'unknown'",
161
+ "ALTER TABLE mesh_messages ADD COLUMN expires_at TEXT DEFAULT NULL",
162
+ "ALTER TABLE mesh_messages ADD COLUMN target_type TEXT DEFAULT 'peer'",
163
+ "ALTER TABLE mesh_messages ADD COLUMN project_path TEXT DEFAULT ''",
164
+ ]
165
+
166
+ _MESH_V346_DDL = """
167
+ -- Read tracking for broadcast/project messages (each peer tracks own reads)
168
+ CREATE TABLE IF NOT EXISTS mesh_reads (
169
+ message_id INTEGER NOT NULL,
170
+ peer_id TEXT NOT NULL,
171
+ read_at TEXT NOT NULL,
172
+ PRIMARY KEY (message_id, peer_id)
173
+ );
174
+
175
+ CREATE INDEX IF NOT EXISTS idx_mesh_messages_target
176
+ ON mesh_messages(target_type, project_path);
177
+ CREATE INDEX IF NOT EXISTS idx_mesh_messages_expires
178
+ ON mesh_messages(expires_at);
179
+ CREATE INDEX IF NOT EXISTS idx_mesh_peers_project
180
+ ON mesh_peers(project_path);
181
+ """
182
+
183
+
184
+ def apply_v346_schema(db_path: str | sqlite3.Connection) -> dict:
185
+ """Apply v3.4.6 mesh enhancements. Idempotent."""
186
+ result = {"applied": [], "errors": []}
187
+
188
+ if isinstance(db_path, sqlite3.Connection):
189
+ conn = db_path
190
+ own_connection = False
191
+ else:
192
+ conn = sqlite3.connect(str(db_path))
193
+ own_connection = True
194
+
195
+ try:
196
+ for alter_sql in _MESH_V346_ALTERS:
197
+ try:
198
+ conn.execute(alter_sql)
199
+ col_name = alter_sql.split("ADD COLUMN")[1].strip().split()[0]
200
+ result["applied"].append(col_name)
201
+ except sqlite3.OperationalError:
202
+ pass # Column already exists
203
+
204
+ try:
205
+ conn.executescript(_MESH_V346_DDL)
206
+ result["applied"].append("mesh_reads table + indexes")
207
+ except sqlite3.OperationalError as e:
208
+ result["errors"].append(f"mesh_v346: {e}")
209
+
210
+ conn.execute(
211
+ "INSERT OR IGNORE INTO schema_version (version, applied_at) VALUES (?, ?)",
212
+ ("3.4.6", __import__("datetime").datetime.now().isoformat()),
213
+ )
214
+ conn.commit()
215
+
216
+ if result["applied"]:
217
+ logger.info("Schema v3.4.6 applied: %s", ", ".join(result["applied"]))
218
+
219
+ except Exception as e:
220
+ result["errors"].append(f"fatal: {e}")
221
+ finally:
222
+ if own_connection:
223
+ conn.close()
224
+
225
+ return result
226
+
227
+
154
228
  def apply_v343_schema(db_path: str | sqlite3.Connection) -> dict:
155
229
  """Apply all v3.4.3 schema changes. Idempotent — safe to call multiple times.
156
230
 
@@ -0,0 +1,136 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SuperLocalMemory V3.4.7 "The Learning Brain" — Schema Extensions.
6
+
7
+ New tables for two-way learning:
8
+ - tool_events: Passive tool usage telemetry
9
+ - behavioral_assertions: Learned patterns with confidence evolution
10
+
11
+ Design rules (inherited):
12
+ - CREATE IF NOT EXISTS for idempotency
13
+ - profile_id where applicable
14
+ - Never ALTER existing column types
15
+
16
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import logging
22
+ import sqlite3
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+ # ---------------------------------------------------------------------------
27
+ # DDL — Tool Events (passive telemetry for learning)
28
+ # ---------------------------------------------------------------------------
29
+
30
+ _TOOL_EVENTS_DDL = """
31
+ CREATE TABLE IF NOT EXISTS tool_events (
32
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
33
+ session_id TEXT NOT NULL,
34
+ profile_id TEXT DEFAULT 'default',
35
+ project_path TEXT DEFAULT '',
36
+ tool_name TEXT NOT NULL,
37
+ event_type TEXT NOT NULL DEFAULT 'invoke',
38
+ input_summary TEXT DEFAULT '',
39
+ output_summary TEXT DEFAULT '',
40
+ duration_ms INTEGER DEFAULT 0,
41
+ metadata TEXT DEFAULT '{}',
42
+ created_at TEXT NOT NULL
43
+ );
44
+
45
+ CREATE INDEX IF NOT EXISTS idx_tool_events_tool
46
+ ON tool_events(tool_name, created_at);
47
+ CREATE INDEX IF NOT EXISTS idx_tool_events_session
48
+ ON tool_events(session_id);
49
+ CREATE INDEX IF NOT EXISTS idx_tool_events_project
50
+ ON tool_events(project_path);
51
+ """
52
+
53
+ # ---------------------------------------------------------------------------
54
+ # DDL — Behavioral Assertions (learned patterns with confidence)
55
+ # ---------------------------------------------------------------------------
56
+
57
+ _ASSERTIONS_DDL = """
58
+ CREATE TABLE IF NOT EXISTS behavioral_assertions (
59
+ id TEXT PRIMARY KEY,
60
+ profile_id TEXT NOT NULL DEFAULT 'default',
61
+ project_path TEXT DEFAULT '',
62
+ trigger_condition TEXT NOT NULL,
63
+ action TEXT NOT NULL,
64
+ category TEXT DEFAULT 'workflow',
65
+ confidence REAL DEFAULT 0.3,
66
+ evidence_fact_ids TEXT DEFAULT '[]',
67
+ evidence_count INTEGER DEFAULT 1,
68
+ reinforcement_count INTEGER DEFAULT 0,
69
+ contradiction_count INTEGER DEFAULT 0,
70
+ last_reinforced_at TEXT,
71
+ last_contradicted_at TEXT,
72
+ source TEXT DEFAULT 'auto',
73
+ created_at TEXT NOT NULL,
74
+ updated_at TEXT NOT NULL
75
+ );
76
+
77
+ CREATE INDEX IF NOT EXISTS idx_assertions_confidence
78
+ ON behavioral_assertions(confidence DESC);
79
+ CREATE INDEX IF NOT EXISTS idx_assertions_project
80
+ ON behavioral_assertions(project_path, profile_id);
81
+ CREATE INDEX IF NOT EXISTS idx_assertions_category
82
+ ON behavioral_assertions(category);
83
+ """
84
+
85
+ # ---------------------------------------------------------------------------
86
+ # Migration runner
87
+ # ---------------------------------------------------------------------------
88
+
89
+ def apply_v347_schema(db_path: str | sqlite3.Connection) -> dict:
90
+ """Apply all v3.4.7 schema changes. Idempotent — safe to call multiple times."""
91
+ result = {"applied": [], "errors": []}
92
+
93
+ if isinstance(db_path, sqlite3.Connection):
94
+ conn = db_path
95
+ own_connection = False
96
+ else:
97
+ conn = sqlite3.connect(str(db_path))
98
+ own_connection = True
99
+
100
+ try:
101
+ # Tool events table
102
+ try:
103
+ conn.executescript(_TOOL_EVENTS_DDL)
104
+ result["applied"].append("tool_events table + indexes")
105
+ except sqlite3.OperationalError as e:
106
+ result["errors"].append(f"tool_events: {e}")
107
+
108
+ # Behavioral assertions table
109
+ try:
110
+ conn.executescript(_ASSERTIONS_DDL)
111
+ result["applied"].append("behavioral_assertions table + indexes")
112
+ except sqlite3.OperationalError as e:
113
+ result["errors"].append(f"behavioral_assertions: {e}")
114
+
115
+ # Mark version
116
+ try:
117
+ conn.execute(
118
+ "INSERT OR IGNORE INTO schema_version (version, applied_at) VALUES (?, ?)",
119
+ ("3.4.7", __import__("datetime").datetime.now().isoformat()),
120
+ )
121
+ except sqlite3.OperationalError:
122
+ pass # schema_version table might not exist yet
123
+
124
+ conn.commit()
125
+
126
+ if result["applied"]:
127
+ logger.info("Schema v3.4.7 applied: %s", ", ".join(result["applied"]))
128
+
129
+ except Exception as e:
130
+ result["errors"].append(f"fatal: {e}")
131
+ logger.error("Schema v3.4.7 migration failed: %s", e)
132
+ finally:
133
+ if own_connection:
134
+ conn.close()
135
+
136
+ return result
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """V2 to V3 database migration.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — Trust Gate (Pre-Operation Checks).
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — Provenance Tracking.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — Bayesian Trust Scorer (Beta Distribution).
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — Trust Signal Recorder with Burst Detection.
@@ -1,6 +1,6 @@
1
- // SPDX-License-Identifier: Elastic-2.0
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
2
  // Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
3
- // Behavioral Learning tab — outcomes, patterns, cross-project transfers (v2.8)
3
+ // Behavioral Learning tab — assertions, outcomes, patterns, tool events (v3.4.7)
4
4
  // NOTE: All dynamic values use textContent or escapeHtml() from core.js before DOM insertion.
5
5
 
6
6
  var _behavioralData = null;
@@ -12,7 +12,7 @@ async function loadBehavioral() {
12
12
  _behavioralData = data;
13
13
 
14
14
  if (!data.available) {
15
- showEmpty('behavioral-patterns-content', 'lightbulb', 'Behavioral learning not available. Upgrade to v2.8.');
15
+ showEmpty('behavioral-patterns-content', 'lightbulb', 'Behavioral learning not available.');
16
16
  return;
17
17
  }
18
18
 
@@ -21,6 +21,22 @@ async function loadBehavioral() {
21
21
  renderBehavioralTransfers(data);
22
22
  renderBehavioralOutcomes(data);
23
23
 
24
+ // v3.4.7: Load behavioral assertions (learned patterns with confidence)
25
+ try {
26
+ var assertResp = await fetch('/api/behavioral/assertions');
27
+ var assertData = await assertResp.json();
28
+ renderBehavioralAssertions(assertData);
29
+ // Update stats with assertion count
30
+ animateCounter('bh-patterns-count', (data.stats || {}).patterns_count + (assertData.count || 0));
31
+ } catch (e) { console.debug('assertions load:', e); }
32
+
33
+ // v3.4.7: Load tool events summary
34
+ try {
35
+ var evResp = await fetch('/api/behavioral/tool-events?limit=20');
36
+ var evData = await evResp.json();
37
+ renderToolEventsSummary(evData);
38
+ } catch (e) { console.debug('tool events load:', e); }
39
+
24
40
  var badge = document.getElementById('behavioral-profile-badge');
25
41
  if (badge) badge.textContent = data.active_profile || 'default';
26
42
  } catch (error) {
@@ -235,6 +251,161 @@ function renderBehavioralOutcomes(data) {
235
251
  container.appendChild(table);
236
252
  }
237
253
 
254
+ // v3.4.7: Render behavioral assertions (learned patterns with confidence evolution)
255
+ function renderBehavioralAssertions(data) {
256
+ var container = document.getElementById('behavioral-patterns-content');
257
+ if (!container) return;
258
+ var assertions = data.assertions || [];
259
+ if (assertions.length === 0) return; // Don't clear existing patterns
260
+
261
+ // Add assertions section header
262
+ var header = document.createElement('div');
263
+ header.className = 'd-flex align-items-center mt-3 mb-2';
264
+ header.innerHTML = '<span class="badge bg-info me-2">NEW</span><strong>Behavioral Assertions (v3.4.7)</strong>';
265
+ container.appendChild(header);
266
+
267
+ for (var i = 0; i < assertions.length; i++) {
268
+ var a = assertions[i];
269
+ var confPct = Math.round((a.confidence || 0) * 100);
270
+ var barColor = confPct >= 70 ? 'bg-success' : (confPct >= 40 ? 'bg-warning' : 'bg-secondary');
271
+
272
+ var card = document.createElement('div');
273
+ card.className = 'card mb-2';
274
+ card.style.cursor = 'pointer';
275
+ card.style.border = '1px solid rgba(255,255,255,0.1)';
276
+ card.style.background = 'rgba(255,255,255,0.03)';
277
+
278
+ var body = document.createElement('div');
279
+ body.className = 'card-body py-2 px-3';
280
+
281
+ // Top row: trigger → action
282
+ var topRow = document.createElement('div');
283
+ topRow.className = 'd-flex justify-content-between align-items-start';
284
+
285
+ var triggerSpan = document.createElement('div');
286
+ triggerSpan.className = 'small';
287
+ var trigBadge = document.createElement('span');
288
+ trigBadge.className = 'badge bg-secondary me-1';
289
+ trigBadge.textContent = a.trigger_condition || '';
290
+ var arrow = document.createElement('span');
291
+ arrow.className = 'text-muted mx-1';
292
+ arrow.textContent = '→';
293
+ var actionSpan = document.createElement('span');
294
+ actionSpan.textContent = a.action || '';
295
+ triggerSpan.appendChild(trigBadge);
296
+ triggerSpan.appendChild(arrow);
297
+ triggerSpan.appendChild(actionSpan);
298
+
299
+ var confBadge = document.createElement('span');
300
+ confBadge.className = 'badge ' + barColor;
301
+ confBadge.textContent = confPct + '%';
302
+ confBadge.title = 'Confidence: ' + confPct + '% (reinforced ' + (a.reinforcement_count || 0) + 'x, contradicted ' + (a.contradiction_count || 0) + 'x)';
303
+
304
+ topRow.appendChild(triggerSpan);
305
+ topRow.appendChild(confBadge);
306
+ body.appendChild(topRow);
307
+
308
+ // Bottom row: category + evidence + confidence bar
309
+ var bottomRow = document.createElement('div');
310
+ bottomRow.className = 'd-flex align-items-center mt-1';
311
+ var catBadge = document.createElement('span');
312
+ catBadge.className = 'badge bg-outline-secondary me-2 small';
313
+ catBadge.style.border = '1px solid rgba(255,255,255,0.2)';
314
+ catBadge.textContent = a.category || '';
315
+ var evidenceSpan = document.createElement('small');
316
+ evidenceSpan.className = 'text-muted me-2';
317
+ evidenceSpan.textContent = (a.evidence_count || 0) + ' evidence';
318
+ var progress = document.createElement('div');
319
+ progress.className = 'progress flex-grow-1';
320
+ progress.style.height = '4px';
321
+ var bar = document.createElement('div');
322
+ bar.className = 'progress-bar ' + barColor;
323
+ bar.style.width = confPct + '%';
324
+ progress.appendChild(bar);
325
+ bottomRow.appendChild(catBadge);
326
+ bottomRow.appendChild(evidenceSpan);
327
+ bottomRow.appendChild(progress);
328
+ body.appendChild(bottomRow);
329
+
330
+ card.appendChild(body);
331
+
332
+ // Click to expand details
333
+ (function(assertion, cardEl) {
334
+ cardEl.addEventListener('click', function() {
335
+ var existing = cardEl.querySelector('.assertion-detail');
336
+ if (existing) { existing.remove(); return; }
337
+ var detail = document.createElement('div');
338
+ detail.className = 'assertion-detail px-3 pb-2 small text-muted';
339
+ detail.innerHTML = '<div>ID: <code>' + escapeHtml(assertion.id) + '</code></div>' +
340
+ '<div>Source: ' + escapeHtml(assertion.source || 'auto') + '</div>' +
341
+ '<div>Project: ' + escapeHtml(assertion.project_path || 'global') + '</div>' +
342
+ '<div>Created: ' + escapeHtml(formatDate(assertion.created_at || '')) + '</div>' +
343
+ '<div>Reinforced: ' + (assertion.reinforcement_count || 0) + 'x | Contradicted: ' + (assertion.contradiction_count || 0) + 'x</div>';
344
+ cardEl.appendChild(detail);
345
+ });
346
+ })(a, card);
347
+
348
+ container.appendChild(card);
349
+ }
350
+ }
351
+
352
+ // v3.4.7: Render tool events summary in behavioral tab
353
+ function renderToolEventsSummary(data) {
354
+ var container = document.getElementById('behavioral-outcomes-content');
355
+ if (!container) return;
356
+ var events = data.events || [];
357
+ if (events.length === 0) return;
358
+
359
+ // Add tool events section
360
+ var header = document.createElement('div');
361
+ header.className = 'd-flex align-items-center mt-3 mb-2';
362
+ header.innerHTML = '<span class="badge bg-info me-2">NEW</span><strong>Recent Tool Events</strong> <small class="text-muted ms-2">(' + data.count + ' shown)</small>';
363
+ container.appendChild(header);
364
+
365
+ var table = document.createElement('table');
366
+ table.className = 'table table-sm table-hover mb-0';
367
+ var thead = document.createElement('thead');
368
+ var headRow = document.createElement('tr');
369
+ ['Tool', 'Event', 'Time'].forEach(function(h) {
370
+ var th = document.createElement('th');
371
+ th.textContent = h;
372
+ headRow.appendChild(th);
373
+ });
374
+ thead.appendChild(headRow);
375
+ table.appendChild(thead);
376
+
377
+ var tbody = document.createElement('tbody');
378
+ for (var i = 0; i < Math.min(events.length, 10); i++) {
379
+ var ev = events[i];
380
+ var row = document.createElement('tr');
381
+ row.style.cursor = 'pointer';
382
+
383
+ var toolCell = document.createElement('td');
384
+ var toolBadge = document.createElement('code');
385
+ toolBadge.className = 'small';
386
+ toolBadge.textContent = ev.tool_name || '';
387
+ toolCell.appendChild(toolBadge);
388
+ row.appendChild(toolCell);
389
+
390
+ var typeCell = document.createElement('td');
391
+ var typeBadge = document.createElement('span');
392
+ var typeColors = { invoke: 'bg-primary', complete: 'bg-success', error: 'bg-danger', correction: 'bg-warning' };
393
+ typeBadge.className = 'badge ' + (typeColors[ev.event_type] || 'bg-secondary');
394
+ typeBadge.textContent = ev.event_type || '';
395
+ typeCell.appendChild(typeBadge);
396
+ row.appendChild(typeCell);
397
+
398
+ var dateCell = document.createElement('td');
399
+ dateCell.className = 'small text-muted';
400
+ dateCell.textContent = formatDate(ev.created_at || '');
401
+ row.appendChild(dateCell);
402
+
403
+ tbody.appendChild(row);
404
+ }
405
+ table.appendChild(tbody);
406
+ container.appendChild(table);
407
+ }
408
+
238
409
  async function reportOutcome() {
239
410
  var memIdsInput = document.getElementById('bh-memory-ids');
240
411
  var outcomeSelect = document.getElementById('bh-outcome');