superlocalmemory 3.4.19 → 3.4.21

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 (170) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +42 -34
  3. package/bin/slm +11 -0
  4. package/bin/slm.bat +12 -0
  5. package/package.json +4 -3
  6. package/pyproject.toml +3 -2
  7. package/scripts/build-slm-hook.ps1 +40 -0
  8. package/scripts/build-slm-hook.sh +45 -0
  9. package/scripts/build_entry.py +452 -0
  10. package/scripts/ci/stage5b_gate.sh +50 -0
  11. package/scripts/postinstall/validation.js +187 -0
  12. package/scripts/postinstall-interactive.js +756 -0
  13. package/scripts/postinstall_binary.js +287 -0
  14. package/scripts/release_manifest.py +273 -0
  15. package/scripts/slm-hook.spec +56 -0
  16. package/skills/slm-build-graph/SKILL.md +423 -0
  17. package/skills/slm-list-recent/SKILL.md +348 -0
  18. package/skills/slm-recall/SKILL.md +343 -0
  19. package/skills/slm-remember/SKILL.md +194 -0
  20. package/skills/slm-show-patterns/SKILL.md +224 -0
  21. package/skills/slm-status/SKILL.md +363 -0
  22. package/skills/slm-switch-profile/SKILL.md +442 -0
  23. package/src/superlocalmemory/cli/commands.py +219 -79
  24. package/src/superlocalmemory/cli/context_commands.py +192 -0
  25. package/src/superlocalmemory/cli/daemon.py +15 -1
  26. package/src/superlocalmemory/cli/db_migrate.py +80 -0
  27. package/src/superlocalmemory/cli/escape_hatch.py +220 -0
  28. package/src/superlocalmemory/cli/main.py +72 -1
  29. package/src/superlocalmemory/core/context_cache.py +397 -0
  30. package/src/superlocalmemory/core/engine.py +38 -2
  31. package/src/superlocalmemory/core/engine_wiring.py +1 -1
  32. package/src/superlocalmemory/core/ram_lock.py +111 -0
  33. package/src/superlocalmemory/core/recall_pipeline.py +433 -3
  34. package/src/superlocalmemory/core/recall_worker.py +8 -3
  35. package/src/superlocalmemory/core/security_primitives.py +635 -0
  36. package/src/superlocalmemory/core/shadow_router.py +319 -0
  37. package/src/superlocalmemory/core/slm_disabled.py +87 -0
  38. package/src/superlocalmemory/core/slmignore.py +125 -0
  39. package/src/superlocalmemory/core/topic_signature.py +143 -0
  40. package/src/superlocalmemory/core/worker_pool.py +14 -3
  41. package/src/superlocalmemory/encoding/cognitive_consolidator.py +2 -2
  42. package/src/superlocalmemory/evolution/budget.py +321 -0
  43. package/src/superlocalmemory/evolution/llm_dispatch.py +508 -0
  44. package/src/superlocalmemory/evolution/skill_evolver.py +144 -94
  45. package/src/superlocalmemory/hooks/_outcome_common.py +506 -0
  46. package/src/superlocalmemory/hooks/adapter_base.py +317 -0
  47. package/src/superlocalmemory/hooks/antigravity_adapter.py +192 -0
  48. package/src/superlocalmemory/hooks/claude_code_hooks.py +33 -1
  49. package/src/superlocalmemory/hooks/context_payload.py +312 -0
  50. package/src/superlocalmemory/hooks/copilot_adapter.py +154 -0
  51. package/src/superlocalmemory/hooks/cross_platform_connector.py +90 -0
  52. package/src/superlocalmemory/hooks/cursor_adapter.py +195 -0
  53. package/src/superlocalmemory/hooks/hook_handlers.py +109 -8
  54. package/src/superlocalmemory/hooks/ide_connector.py +25 -2
  55. package/src/superlocalmemory/hooks/post_tool_async_hook.py +165 -0
  56. package/src/superlocalmemory/hooks/post_tool_outcome_hook.py +223 -0
  57. package/src/superlocalmemory/hooks/prewarm_auth.py +170 -0
  58. package/src/superlocalmemory/hooks/session_registry.py +186 -0
  59. package/src/superlocalmemory/hooks/stop_outcome_hook.py +134 -0
  60. package/src/superlocalmemory/hooks/sync_loop.py +114 -0
  61. package/src/superlocalmemory/hooks/user_prompt_hook.py +128 -0
  62. package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +202 -0
  63. package/src/superlocalmemory/infra/backup.py +3 -3
  64. package/src/superlocalmemory/infra/cloud_backup.py +2 -2
  65. package/src/superlocalmemory/infra/event_bus.py +2 -2
  66. package/src/superlocalmemory/infra/webhook_dispatcher.py +3 -3
  67. package/src/superlocalmemory/learning/arm_catalog.py +99 -0
  68. package/src/superlocalmemory/learning/bandit.py +526 -0
  69. package/src/superlocalmemory/learning/bandit_cache.py +133 -0
  70. package/src/superlocalmemory/learning/behavioral.py +53 -1
  71. package/src/superlocalmemory/learning/consolidation_cycle.py +381 -0
  72. package/src/superlocalmemory/learning/consolidation_worker.py +188 -520
  73. package/src/superlocalmemory/learning/database.py +256 -0
  74. package/src/superlocalmemory/learning/dedup_hnsw.py +413 -0
  75. package/src/superlocalmemory/learning/ensemble.py +300 -0
  76. package/src/superlocalmemory/learning/fact_outcome_joins.py +207 -0
  77. package/src/superlocalmemory/learning/forgetting_scheduler.py +55 -0
  78. package/src/superlocalmemory/learning/hnsw_dedup.py +69 -0
  79. package/src/superlocalmemory/learning/labeler.py +87 -0
  80. package/src/superlocalmemory/learning/legacy_migration.py +277 -0
  81. package/src/superlocalmemory/learning/memory_merge.py +160 -0
  82. package/src/superlocalmemory/learning/model_cache.py +269 -0
  83. package/src/superlocalmemory/learning/model_rollback.py +278 -0
  84. package/src/superlocalmemory/learning/outcome_queue.py +284 -0
  85. package/src/superlocalmemory/learning/pattern_miner.py +415 -0
  86. package/src/superlocalmemory/learning/pattern_miner_constants.py +47 -0
  87. package/src/superlocalmemory/learning/ranker.py +225 -81
  88. package/src/superlocalmemory/learning/ranker_common.py +163 -0
  89. package/src/superlocalmemory/learning/ranker_retrain_legacy.py +202 -0
  90. package/src/superlocalmemory/learning/ranker_retrain_online.py +411 -0
  91. package/src/superlocalmemory/learning/reward.py +777 -0
  92. package/src/superlocalmemory/learning/reward_archive.py +210 -0
  93. package/src/superlocalmemory/learning/reward_boost.py +201 -0
  94. package/src/superlocalmemory/learning/reward_proxy.py +326 -0
  95. package/src/superlocalmemory/learning/shadow_test.py +524 -0
  96. package/src/superlocalmemory/learning/signal_worker.py +270 -0
  97. package/src/superlocalmemory/learning/signals.py +314 -0
  98. package/src/superlocalmemory/learning/trigram_index.py +547 -0
  99. package/src/superlocalmemory/mcp/server.py +5 -5
  100. package/src/superlocalmemory/mcp/tools_context.py +183 -0
  101. package/src/superlocalmemory/mcp/tools_core.py +92 -27
  102. package/src/superlocalmemory/parameterization/soft_prompt_generator.py +13 -0
  103. package/src/superlocalmemory/retrieval/engine.py +52 -0
  104. package/src/superlocalmemory/server/api.py +2 -2
  105. package/src/superlocalmemory/server/bandit_loops.py +140 -0
  106. package/src/superlocalmemory/server/middleware/__init__.py +11 -0
  107. package/src/superlocalmemory/server/middleware/security_headers.py +144 -0
  108. package/src/superlocalmemory/server/routes/backup.py +36 -13
  109. package/src/superlocalmemory/server/routes/behavioral.py +50 -19
  110. package/src/superlocalmemory/server/routes/brain.py +1234 -0
  111. package/src/superlocalmemory/server/routes/data_io.py +4 -4
  112. package/src/superlocalmemory/server/routes/events.py +2 -2
  113. package/src/superlocalmemory/server/routes/helpers.py +1 -1
  114. package/src/superlocalmemory/server/routes/learning.py +192 -7
  115. package/src/superlocalmemory/server/routes/memories.py +189 -1
  116. package/src/superlocalmemory/server/routes/prewarm.py +171 -0
  117. package/src/superlocalmemory/server/routes/profiles.py +3 -3
  118. package/src/superlocalmemory/server/routes/token.py +88 -0
  119. package/src/superlocalmemory/server/routes/ws.py +5 -5
  120. package/src/superlocalmemory/server/security_middleware.py +13 -7
  121. package/src/superlocalmemory/server/ui.py +2 -2
  122. package/src/superlocalmemory/server/unified_daemon.py +335 -3
  123. package/src/superlocalmemory/storage/migration_runner.py +545 -0
  124. package/src/superlocalmemory/storage/migrations/M001_add_signal_features_columns.py +67 -0
  125. package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +132 -0
  126. package/src/superlocalmemory/storage/migrations/M003_migration_log.py +38 -0
  127. package/src/superlocalmemory/storage/migrations/M004_cross_platform_sync_log.py +46 -0
  128. package/src/superlocalmemory/storage/migrations/M005_bandit_tables.py +75 -0
  129. package/src/superlocalmemory/storage/migrations/M006_action_outcomes_reward.py +75 -0
  130. package/src/superlocalmemory/storage/migrations/M007_pending_outcomes.py +63 -0
  131. package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +54 -0
  132. package/src/superlocalmemory/storage/migrations/M010_evolution_config.py +75 -0
  133. package/src/superlocalmemory/storage/migrations/M011_archive_and_merge.py +87 -0
  134. package/src/superlocalmemory/storage/migrations/M012_shadow_observations.py +72 -0
  135. package/src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py +55 -0
  136. package/src/superlocalmemory/storage/migrations/__init__.py +81 -0
  137. package/src/superlocalmemory/storage/models.py +4 -0
  138. package/src/superlocalmemory/ui/css/brain.css +409 -0
  139. package/src/superlocalmemory/ui/css/legacy-dashboard.css +645 -0
  140. package/src/superlocalmemory/ui/index.html +459 -1345
  141. package/src/superlocalmemory/ui/js/brain.js +1321 -0
  142. package/src/superlocalmemory/ui/js/clusters.js +123 -4
  143. package/src/superlocalmemory/ui/js/init.js +48 -39
  144. package/src/superlocalmemory/ui/js/memories.js +88 -2
  145. package/src/superlocalmemory/ui/js/modal.js +71 -1
  146. package/src/superlocalmemory/ui/js/ng-shell.js +101 -88
  147. package/src/superlocalmemory/ui/js/trust-dashboard.js +168 -25
  148. package/src/superlocalmemory/ui/vendor/bootstrap-icons/bootstrap-icons.css +2018 -0
  149. package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
  150. package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
  151. package/src/superlocalmemory/ui/vendor/bootstrap.bundle.min.js +7 -0
  152. package/src/superlocalmemory/ui/vendor/bootstrap.min.css +6 -0
  153. package/src/superlocalmemory/ui/vendor/d3.v7.min.js +2 -0
  154. package/src/superlocalmemory/ui/vendor/graphology-library.min.js +2 -0
  155. package/src/superlocalmemory/ui/vendor/graphology.umd.min.js +2 -0
  156. package/src/superlocalmemory/ui/vendor/inter-ui/inter-variable.min.css +8 -0
  157. package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable-Italic.woff2 +0 -0
  158. package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable.woff2 +0 -0
  159. package/src/superlocalmemory/ui/vendor/sigma.min.js +1 -0
  160. package/src/superlocalmemory/ui/js/behavioral.js +0 -447
  161. package/src/superlocalmemory/ui/js/graph-core.js +0 -447
  162. package/src/superlocalmemory/ui/js/graph-interactions.js +0 -351
  163. package/src/superlocalmemory/ui/js/learning.js +0 -435
  164. package/src/superlocalmemory/ui/js/patterns.js +0 -93
  165. package/src/superlocalmemory.egg-info/PKG-INFO +0 -647
  166. package/src/superlocalmemory.egg-info/SOURCES.txt +0 -335
  167. package/src/superlocalmemory.egg-info/dependency_links.txt +0 -1
  168. package/src/superlocalmemory.egg-info/entry_points.txt +0 -2
  169. package/src/superlocalmemory.egg-info/requires.txt +0 -58
  170. package/src/superlocalmemory.egg-info/top_level.txt +0 -1
@@ -1,687 +1,49 @@
1
1
  <!DOCTYPE html>
2
- <html lang="en" data-bs-theme="light">
2
+ <html lang="en" data-bs-theme="dark">
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>SuperLocalMemory V3 — Dashboard</title>
7
7
 
8
- <!-- Bootstrap CSS -->
9
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
10
- <!-- Bootstrap Icons -->
11
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
12
- <!-- Inter Variable (Linear's signature typeface with cv01/ss03) — via jsdelivr (CSP-allowed) -->
13
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/inter-ui@4.1.0/inter-variable.min.css">
8
+ <!-- Bootstrap CSS (vendored locally v3.4.21 — no CDN calls, works offline) -->
9
+ <link href="static/vendor/bootstrap.min.css" rel="stylesheet">
10
+ <!-- Bootstrap Icons (vendored) -->
11
+ <link rel="stylesheet" href="static/vendor/bootstrap-icons/bootstrap-icons.css">
12
+ <!-- Inter Variable typeface (vendored) -->
13
+ <link rel="stylesheet" href="static/vendor/inter-ui/inter-variable.min.css">
14
14
  <!-- Neural Glass Design System v1.0 -->
15
15
  <link rel="stylesheet" href="static/css/neural-glass.css?v=345">
16
+ <!-- Brain tab styles (v3.4.21) -->
17
+ <link rel="stylesheet" href="static/css/brain.css?v=34321">
16
18
 
17
- <style>
18
- :root {
19
- --slm-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
20
- --slm-gradient-success: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
21
- --slm-gradient-info: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
22
- --slm-gradient-warning: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
23
- }
24
-
25
- html {
26
- scroll-behavior: smooth;
27
- }
28
-
29
- body {
30
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
31
- overflow-x: auto;
32
- overflow-y: scroll;
33
- min-width: min-content;
34
- }
35
-
36
- [data-bs-theme="light"] body,
37
- [data-bs-theme="light"] {
38
- background: #f8f9fa;
39
- }
40
-
41
- .navbar {
42
- background: var(--slm-gradient);
43
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
44
- }
45
-
46
- /* Cloud account widget — sidebar (v3.4.10) */
47
- #ng-account-widget:hover { background: rgba(255,255,255,0.06) !important; }
48
- .account-dest-item { padding: 6px 0; display: flex; align-items: center; gap: 8px; }
49
- .account-dest-badge { font-size: 10px; padding: 1px 6px; border-radius: 4px; }
50
- .account-dest-badge.synced { background: rgba(0,212,170,0.15); color: #00D4AA; }
51
- .account-dest-badge.failed { background: rgba(255,71,87,0.15); color: #ff4757; }
52
- .account-dest-badge.never { background: rgba(255,255,255,0.06); color: #888; }
53
-
54
- /* Stat cards with gradient backgrounds */
55
- .stat-card {
56
- border: none;
57
- border-radius: 12px;
58
- box-shadow: 0 4px 15px rgba(0,0,0,0.08);
59
- transition: transform 0.2s, box-shadow 0.2s;
60
- overflow: hidden;
61
- position: relative;
62
- }
63
-
64
- .stat-card:hover {
65
- transform: translateY(-5px);
66
- box-shadow: 0 8px 25px rgba(0,0,0,0.12);
67
- }
68
-
69
- .stat-card .stat-bg {
70
- position: absolute;
71
- top: 0; left: 0; right: 0; bottom: 0;
72
- opacity: 0.08;
73
- border-radius: 12px;
74
- }
75
-
76
- .stat-card-memories .stat-bg { background: var(--slm-gradient); }
77
- .stat-card-clusters .stat-bg { background: var(--slm-gradient-success); }
78
- .stat-card-nodes .stat-bg { background: var(--slm-gradient-info); }
79
- .stat-card-edges .stat-bg { background: var(--slm-gradient-warning); }
80
-
81
- .stat-icon {
82
- font-size: 2rem;
83
- opacity: 0.8;
84
- }
85
-
86
- .stat-value {
87
- font-size: 1.75rem;
88
- font-weight: 700;
89
- margin: 0;
90
- }
91
-
92
- .tab-content {
93
- min-height: 700px;
94
- overflow-x: auto;
95
- overflow-y: visible;
96
- }
97
-
98
- .tab-pane {
99
- overflow-x: auto;
100
- overflow-y: visible;
101
- }
102
-
103
- #graph-container {
104
- background: var(--bs-body-bg);
105
- border-radius: 10px;
106
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
107
- height: 600px !important;
108
- max-height: 600px;
109
- width: 100% !important;
110
- position: relative;
111
- overflow: hidden;
112
- /* Mobile touch support - prevent default gestures */
113
- touch-action: none;
114
- -webkit-user-select: none;
115
- -moz-user-select: none;
116
- -ms-user-select: none;
117
- user-select: none;
118
- }
119
-
120
- #graph-container canvas {
121
- max-width: 100% !important;
122
- max-height: 100% !important;
123
- }
124
-
125
- .node {
126
- cursor: pointer;
127
- stroke: #fff;
128
- stroke-width: 2px;
129
- }
130
-
131
- .link {
132
- stroke: #999;
133
- stroke-opacity: 0.6;
134
- }
135
-
136
- .node-label {
137
- font-size: 10px;
138
- pointer-events: none;
139
- fill: #333;
140
- }
141
-
142
- /* Memory table styling */
143
- .memory-table {
144
- font-size: 0.9rem;
145
- }
146
-
147
- .memory-table tbody tr {
148
- cursor: pointer;
149
- transition: background-color 0.15s;
150
- }
151
-
152
- .memory-table tbody tr:hover {
153
- background-color: rgba(102, 126, 234, 0.08) !important;
154
- }
155
-
156
- .memory-content {
157
- max-width: 350px;
158
- overflow: hidden;
159
- text-overflow: ellipsis;
160
- white-space: nowrap;
161
- }
162
-
163
- .badge-importance {
164
- min-width: 30px;
165
- }
166
-
167
- .search-box {
168
- border-radius: 20px;
169
- }
170
-
171
- .cluster-card {
172
- border-left: 4px solid;
173
- margin-bottom: 1rem;
174
- }
175
-
176
- .entity-badge {
177
- margin: 2px;
178
- font-size: 0.8rem;
179
- }
180
-
181
- /* Loading spinner */
182
- .loading {
183
- text-align: center;
184
- padding: 60px 40px;
185
- color: #888;
186
- }
187
-
188
- .loading .spinner-border {
189
- width: 2rem;
190
- height: 2rem;
191
- margin-bottom: 12px;
192
- }
193
-
194
- /* Empty state */
195
- .empty-state {
196
- text-align: center;
197
- padding: 60px 40px;
198
- color: #888;
199
- }
200
-
201
- .empty-state i {
202
- font-size: 3rem;
203
- opacity: 0.3;
204
- margin-bottom: 12px;
205
- }
206
-
207
- .tooltip-custom {
208
- position: absolute;
209
- padding: 10px;
210
- background: rgba(0,0,0,0.8);
211
- color: white;
212
- border-radius: 5px;
213
- pointer-events: none;
214
- font-size: 12px;
215
- z-index: 1000;
216
- max-width: 300px;
217
- }
218
-
219
- .timeline-chart {
220
- min-height: 300px;
221
- }
222
-
223
- /* Score bar for search results */
224
- .score-bar-container {
225
- width: 80px;
226
- display: inline-block;
227
- vertical-align: middle;
228
- }
229
-
230
- .score-bar {
231
- height: 8px;
232
- border-radius: 4px;
233
- background: #e9ecef;
234
- overflow: hidden;
235
- }
236
-
237
- .score-bar-fill {
238
- height: 100%;
239
- border-radius: 4px;
240
- transition: width 0.4s ease;
241
- }
242
-
243
- .score-label {
244
- font-size: 0.75rem;
245
- font-weight: 600;
246
- min-width: 36px;
247
- display: inline-block;
248
- text-align: right;
249
- margin-right: 6px;
250
- vertical-align: middle;
251
- }
252
-
253
- /* Project select in navbar */
254
- .profile-select {
255
- background: rgba(255,255,255,0.15);
256
- border: 1px solid rgba(255,255,255,0.3);
257
- color: white;
258
- border-radius: 20px;
259
- padding: 2px 28px 2px 10px;
260
- font-size: 0.85rem;
261
- min-width: 120px;
262
- cursor: pointer;
263
- }
264
-
265
- .profile-select option {
266
- background: var(--bs-body-bg);
267
- color: var(--bs-body-color);
268
- }
269
-
270
- /* Sortable table headers */
271
- .sortable {
272
- cursor: pointer;
273
- user-select: none;
274
- position: relative;
275
- padding-right: 18px !important;
276
- }
277
-
278
- .sortable:hover {
279
- background-color: rgba(102, 126, 234, 0.08);
280
- }
281
-
282
- .sortable::after {
283
- content: '\F282';
284
- font-family: 'bootstrap-icons';
285
- position: absolute;
286
- right: 4px;
287
- opacity: 0.3;
288
- font-size: 0.7rem;
289
- }
290
-
291
- .sortable.sort-asc::after {
292
- content: '\F235';
293
- opacity: 0.8;
294
- }
295
-
296
- .sortable.sort-desc::after {
297
- content: '\F229';
298
- opacity: 0.8;
299
- }
300
-
301
- /* Confidence bar for patterns */
302
- .confidence-bar {
303
- height: 6px;
304
- border-radius: 3px;
305
- background: var(--bs-border-color);
306
- overflow: hidden;
307
- margin-top: 4px;
308
- }
309
-
310
- .confidence-fill {
311
- height: 100%;
312
- border-radius: 3px;
313
- transition: width 0.6s ease;
314
- }
315
-
316
- /* Backup status cards */
317
- .backup-stat {
318
- padding: 12px;
319
- border-radius: 8px;
320
- background: var(--bs-tertiary-bg);
321
- text-align: center;
322
- }
323
-
324
- .backup-stat .value {
325
- font-size: 1.3rem;
326
- font-weight: 700;
327
- }
328
-
329
- .backup-stat .label {
330
- font-size: 0.75rem;
331
- color: var(--bs-secondary-color);
332
- text-transform: uppercase;
333
- }
334
-
335
- /* Project delete button */
336
- .btn-delete-profile {
337
- padding: 2px 8px;
338
- font-size: 0.75rem;
339
- }
340
-
341
- /* Dark mode toggle button */
342
- .theme-toggle {
343
- background: none;
344
- border: 1px solid rgba(255,255,255,0.3);
345
- color: white;
346
- border-radius: 20px;
347
- padding: 4px 12px;
348
- font-size: 0.9rem;
349
- cursor: pointer;
350
- transition: background 0.2s;
351
- }
352
-
353
- .theme-toggle:hover {
354
- background: rgba(255,255,255,0.15);
355
- }
356
-
357
- /* Modal content formatting */
358
- .memory-detail-content {
359
- white-space: pre-wrap;
360
- word-break: break-word;
361
- font-size: 0.95rem;
362
- line-height: 1.6;
363
- max-height: 400px;
364
- overflow-y: auto;
365
- padding: 16px;
366
- background: var(--bs-tertiary-bg);
367
- border-radius: 8px;
368
- }
369
-
370
- .memory-detail-meta dt {
371
- font-weight: 600;
372
- color: var(--bs-secondary-color);
373
- font-size: 0.8rem;
374
- text-transform: uppercase;
375
- letter-spacing: 0.5px;
376
- }
377
-
378
- .memory-detail-meta dd {
379
- margin-bottom: 12px;
380
- }
381
-
382
- /* Export dropdown */
383
- .export-dropdown .dropdown-menu {
384
- min-width: 200px;
385
- }
386
-
387
- /* Tab badge */
388
- .tab-count {
389
- font-size: 0.7rem;
390
- vertical-align: super;
391
- margin-left: 2px;
392
- }
393
-
394
- /* Footer */
395
- footer {
396
- text-align: center;
397
- padding: 20px;
398
- margin-top: 40px;
399
- border-top: 1px solid var(--bs-border-color);
400
- color: var(--bs-secondary-color);
401
- }
402
-
403
- footer a {
404
- color: #667eea;
405
- }
406
-
407
- [data-bs-theme="dark"] footer a {
408
- color: #8fa4ff;
409
- }
410
-
411
- /* ========================================
412
- MOBILE & TABLET RESPONSIVE STYLES
413
- ======================================== */
414
-
415
- /* Tablet (768px and below) */
416
- @media (max-width: 768px) {
417
- .navbar-brand {
418
- font-size: 1rem;
419
- }
420
-
421
- #navbar-subtitle {
422
- display: none !important;
423
- }
424
-
425
- .stat-card {
426
- margin-bottom: 12px;
427
- }
428
-
429
- .stat-value {
430
- font-size: 1.4rem;
431
- }
432
-
433
- .stat-icon {
434
- font-size: 1.5rem;
435
- }
436
-
437
- /* Graph container - smaller on tablet */
438
- #graph-container {
439
- height: 450px !important;
440
- max-height: 450px;
441
- }
442
-
443
- /* Stack controls vertically on tablet */
444
- .tab-pane .row > .col-md-6,
445
- .tab-pane .row > .col-md-8,
446
- .tab-pane .row > .col-md-4 {
447
- margin-bottom: 10px;
448
- }
449
-
450
- /* Smaller buttons on mobile */
451
- .btn-sm {
452
- font-size: 0.8rem;
453
- padding: 4px 8px;
454
- }
455
-
456
- /* Memory table - hide less important columns */
457
- .memory-table th:nth-child(4),
458
- .memory-table td:nth-child(4),
459
- .memory-table th:nth-child(5),
460
- .memory-table td:nth-child(5) {
461
- display: none;
462
- }
463
-
464
- .memory-content {
465
- max-width: 200px;
466
- }
467
- }
468
-
469
- /* Mobile (480px and below) */
470
- @media (max-width: 480px) {
471
- body {
472
- font-size: 0.9rem;
473
- }
474
-
475
- .navbar-brand {
476
- font-size: 0.9rem;
477
- }
478
-
479
- .container-fluid {
480
- padding-left: 10px;
481
- padding-right: 10px;
482
- }
483
-
484
- /* Stat cards - 2 per row on mobile */
485
- .col-6.mb-3 {
486
- padding-left: 5px;
487
- padding-right: 5px;
488
- }
489
-
490
- .stat-card {
491
- padding: 12px 8px !important;
492
- }
493
-
494
- .stat-value {
495
- font-size: 1.2rem;
496
- }
497
-
498
- .stat-icon {
499
- font-size: 1.2rem;
500
- }
501
-
502
- .stat-card small {
503
- font-size: 0.7rem;
504
- }
505
-
506
- /* Graph container - even smaller on mobile */
507
- #graph-container {
508
- height: 350px !important;
509
- max-height: 350px;
510
- border-radius: 6px;
511
- }
512
-
513
- /* Tabs - smaller text */
514
- .nav-tabs .nav-link {
515
- font-size: 0.8rem;
516
- padding: 8px 10px;
517
- }
518
-
519
- .nav-tabs .nav-link i {
520
- display: none;
521
- }
522
-
523
- /* Search controls - stack vertically */
524
- #memories-pane .row > div {
525
- margin-bottom: 8px;
526
- }
527
-
528
- /* Memory table - show only essentials */
529
- .memory-table {
530
- font-size: 0.8rem;
531
- }
532
-
533
- .memory-table th:nth-child(3),
534
- .memory-table td:nth-child(3),
535
- .memory-table th:nth-child(4),
536
- .memory-table td:nth-child(4),
537
- .memory-table th:nth-child(5),
538
- .memory-table td:nth-child(5) {
539
- display: none;
540
- }
541
-
542
- .memory-content {
543
- max-width: 150px;
544
- font-size: 0.75rem;
545
- }
546
-
547
- /* Modal - full screen on mobile */
548
- .modal-dialog {
549
- margin: 0;
550
- max-width: 100%;
551
- height: 100vh;
552
- }
553
-
554
- .modal-content {
555
- height: 100%;
556
- border-radius: 0;
557
- }
558
-
559
- /* Dropdown controls */
560
- .form-select-sm {
561
- font-size: 0.8rem;
562
- padding: 4px 8px;
563
- }
564
-
565
- /* Project select - smaller */
566
- .profile-select {
567
- min-width: 90px;
568
- font-size: 0.75rem;
569
- padding: 2px 24px 2px 8px;
570
- }
571
-
572
- /* Theme toggle - smaller */
573
- .theme-toggle {
574
- font-size: 0.8rem;
575
- padding: 3px 10px;
576
- }
577
-
578
- /* Footer - smaller text */
579
- footer {
580
- font-size: 0.75rem;
581
- padding: 15px;
582
- margin-top: 20px;
583
- }
584
-
585
- /* Graph controls - stack vertically on mobile */
586
- #graph-pane .card .row > div {
587
- margin-bottom: 10px;
588
- }
589
-
590
- /* Hide "Show All Memories" button text on mobile, icon only */
591
- #graph-status-filtered .btn span {
592
- display: none;
593
- }
594
-
595
- #graph-status-filtered .btn i::after {
596
- content: ' All';
597
- }
598
- }
599
-
600
- /* Landscape mobile (small height) */
601
- @media (max-height: 500px) and (orientation: landscape) {
602
- #graph-container {
603
- height: 250px !important;
604
- max-height: 250px;
605
- }
606
-
607
- .stat-card {
608
- padding: 8px !important;
609
- }
610
-
611
- .stat-value {
612
- font-size: 1rem;
613
- }
614
-
615
- .navbar {
616
- padding: 5px 0;
617
- }
618
- }
619
-
620
- /* Touch feedback for interactive elements */
621
- @media (hover: none) and (pointer: coarse) {
622
- /* This targets touch devices only */
623
- .btn:active,
624
- .nav-link:active,
625
- .sortable:active {
626
- opacity: 0.7;
627
- transform: scale(0.98);
628
- }
629
-
630
- /* Larger tap targets on touch devices */
631
- .btn {
632
- min-height: 44px;
633
- min-width: 44px;
634
- }
635
-
636
- .nav-tabs .nav-link {
637
- min-height: 44px;
638
- }
639
-
640
- /* Prevent accidental double-tap zoom on buttons */
641
- .btn,
642
- .nav-link,
643
- .form-control,
644
- .form-select {
645
- touch-action: manipulation;
646
- }
647
- }
648
- </style>
19
+ <!-- Legacy dashboard styles (v3.4.21 — extracted to external file, no rule changes) -->
20
+ <link rel="stylesheet" href="static/css/legacy-dashboard.css?v=34422">
649
21
  </head>
650
- <body>
651
- <!-- Navbar -->
652
- <nav class="navbar navbar-dark mb-4">
653
- <div class="container-fluid">
654
- <span class="navbar-brand mb-0 h1">
655
- <i class="bi bi-diagram-3"></i> SuperLocalMemory V3
656
- <span id="mode-badge" class="badge bg-light text-dark ms-2">...</span>
657
- </span>
658
- <div class="d-flex align-items-center gap-3">
659
- <div class="d-flex align-items-center gap-2">
660
- <i class="bi bi-person-circle text-white-50"></i>
661
- <select class="form-select form-select-sm profile-select" id="profile-select" title="Switch profile">
662
- <option value="default">default</option>
663
- </select>
664
- <button class="btn btn-sm theme-toggle" id="add-profile-btn" title="Create new profile" style="padding:2px 8px;font-size:1rem;line-height:1;">
665
- <i class="bi bi-plus-lg"></i>
666
- </button>
667
- </div>
668
- <span class="text-white-50 d-none d-md-inline" id="navbar-subtitle">Knowledge Graph Explorer</span>
669
- <a href="https://github.com/qualixar/superlocalmemory" target="_blank" class="btn btn-sm btn-outline-light ms-2 d-none d-md-inline-flex align-items-center" style="font-size:0.75rem; gap:4px;" title="Star us on GitHub">
670
- <i class="bi bi-github"></i> <i class="bi bi-star"></i> Star
671
- </a>
672
- <button class="btn btn-sm theme-toggle" id="refresh-dashboard-btn" onclick="refreshDashboard()" title="Refresh Dashboard" style="padding:4px 8px;">
673
- <i class="bi bi-arrow-clockwise" aria-hidden="true"></i>
674
- </button>
675
- <button class="theme-toggle" id="theme-toggle" onclick="toggleDarkMode()" aria-label="Toggle dark mode">
676
- <i class="bi bi-sun-fill" id="theme-icon" aria-hidden="true"></i>
677
- </button>
678
- </div>
679
- </div>
680
- </nav>
22
+ <body style="background: #0a0e1a;">
23
+ <!-- Pre-mount: elements ng-shell.js relocates into the sidebar + footer.
24
+ Hidden on initial paint so there's no flash of the old Bootstrap
25
+ navbar. ng-shell moves these into their final homes on mount. -->
26
+ <div id="ng-premount" style="display: none;">
27
+ <select class="form-select form-select-sm profile-select" id="profile-select" title="Switch profile">
28
+ <option value="default">default</option>
29
+ </select>
30
+ <button class="btn btn-sm theme-toggle" id="add-profile-btn" title="Create new profile" style="padding:2px 8px;font-size:1rem;line-height:1;">
31
+ <i class="bi bi-plus-lg"></i>
32
+ </button>
33
+ <span id="mode-badge" class="badge">...</span>
34
+ <button class="btn btn-sm theme-toggle" id="refresh-dashboard-btn" onclick="refreshDashboard()" title="Refresh Dashboard" style="padding:4px 8px;">
35
+ <i class="bi bi-arrow-clockwise" aria-hidden="true"></i>
36
+ </button>
37
+ <button class="theme-toggle" id="theme-toggle" onclick="toggleDarkMode()" aria-label="Toggle dark mode">
38
+ <i class="bi bi-sun-fill" id="theme-icon" aria-hidden="true"></i>
39
+ </button>
40
+ </div>
681
41
 
682
42
  <div class="container-fluid">
683
- <!-- Stats Overview -->
684
- <div class="row mb-4" id="stats-container">
43
+ <!-- Stats Overview — hidden until ng-shell.js relocates this block
44
+ into the Dashboard pane. Prevents the flash of pre-glass stat
45
+ cards at the top of the page on initial load (v3.4.21 FOUC fix). -->
46
+ <div class="row mb-4" id="stats-container" style="display: none;">
685
47
  <div class="col-md-3 col-6 mb-3">
686
48
  <div class="card stat-card stat-card-memories text-center p-3">
687
49
  <div class="stat-bg"></div>
@@ -716,93 +78,28 @@
716
78
  </div>
717
79
  </div>
718
80
 
719
- <!-- Main Content Tabs -->
720
- <ul class="nav nav-tabs flex-wrap mb-3" id="mainTabs" role="tablist">
721
- <li class="nav-item">
722
- <button class="nav-link active" id="dashboard-tab" data-bs-toggle="tab" data-bs-target="#dashboard-pane">
723
- <i class="bi bi-speedometer2"></i> Dashboard
724
- </button>
725
- </li>
726
- <li class="nav-item">
727
- <button class="nav-link" id="graph-tab" data-bs-toggle="tab" data-bs-target="#graph-pane">
728
- <i class="bi bi-diagram-3"></i> Knowledge Graph
729
- </button>
730
- </li>
731
- <li class="nav-item">
732
- <button class="nav-link" id="memories-tab" data-bs-toggle="tab" data-bs-target="#memories-pane">
733
- <i class="bi bi-list-ul"></i> Memories
734
- </button>
735
- </li>
736
- <li class="nav-item">
737
- <button class="nav-link" id="recall-lab-tab" data-bs-toggle="tab" data-bs-target="#recall-lab-pane">
738
- <i class="bi bi-search-heart"></i> Recall Lab
739
- </button>
740
- </li>
741
- <li class="nav-item">
742
- <button class="nav-link" id="clusters-tab" data-bs-toggle="tab" data-bs-target="#clusters-pane">
743
- <i class="bi bi-collection"></i> Clusters
744
- </button>
745
- </li>
746
- <li class="nav-item">
747
- <button class="nav-link" id="patterns-tab" data-bs-toggle="tab" data-bs-target="#patterns-pane">
748
- <i class="bi bi-puzzle"></i> Patterns
749
- </button>
750
- </li>
751
- <li class="nav-item">
752
- <button class="nav-link" id="timeline-tab" data-bs-toggle="tab" data-bs-target="#timeline-pane">
753
- <i class="bi bi-clock-history"></i> Timeline
754
- </button>
755
- </li>
756
- <li class="nav-item">
757
- <button class="nav-link" id="learning-tab" data-bs-toggle="tab" data-bs-target="#learning-pane">
758
- <i class="bi bi-mortarboard"></i> Learning
759
- </button>
760
- </li>
761
- <li class="nav-item">
762
- <button class="nav-link" id="events-tab" data-bs-toggle="tab" data-bs-target="#events-pane">
763
- <i class="bi bi-broadcast"></i> Live Events
764
- </button>
765
- </li>
766
- <li class="nav-item">
767
- <button class="nav-link" id="agents-tab" data-bs-toggle="tab" data-bs-target="#agents-pane">
768
- <i class="bi bi-robot"></i> Agents
769
- </button>
770
- </li>
771
- <li class="nav-item">
772
- <button class="nav-link" id="trust-tab" data-bs-toggle="tab" data-bs-target="#trust-pane">
773
- <i class="bi bi-shield-check"></i> Trust
774
- </button>
775
- </li>
776
- <li class="nav-item" role="presentation">
777
- <button class="nav-link" id="lifecycle-tab" data-bs-toggle="tab" data-bs-target="#lifecycle-pane" type="button" role="tab">
778
- <i class="bi bi-hourglass-split"></i> Lifecycle
779
- </button>
780
- </li>
781
- <li class="nav-item" role="presentation">
782
- <button class="nav-link" id="behavioral-tab" data-bs-toggle="tab" data-bs-target="#behavioral-pane" type="button" role="tab">
783
- <i class="bi bi-lightbulb"></i> Behavioral
784
- </button>
785
- </li>
786
- <li class="nav-item" role="presentation">
787
- <button class="nav-link" id="compliance-tab" data-bs-toggle="tab" data-bs-target="#compliance-pane" type="button" role="tab">
788
- <i class="bi bi-shield-lock"></i> Compliance
789
- </button>
790
- </li>
791
- <li class="nav-item">
792
- <button class="nav-link" id="math-health-tab" data-bs-toggle="tab" data-bs-target="#math-health-pane">
793
- <i class="bi bi-calculator"></i> Math Health
794
- </button>
795
- </li>
796
- <li class="nav-item">
797
- <button class="nav-link" id="ide-tab" data-bs-toggle="tab" data-bs-target="#ide-pane">
798
- <i class="bi bi-plug"></i> IDEs
799
- </button>
800
- </li>
801
- <li class="nav-item">
802
- <button class="nav-link" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings-pane">
803
- <i class="bi bi-gear"></i> Settings
804
- </button>
805
- </li>
81
+ <!-- Main content tabs — Bootstrap nav-tabs row removed (v3.4.21,
82
+ Domain 2). Sidebar (built by ng-shell.js) is the sole
83
+ navigation. Hidden tab buttons below keep the Bootstrap
84
+ ``shown.bs.tab`` event contract alive ng-shell's
85
+ ``activateTab`` dispatches on them, and brain.js / other
86
+ listeners fire normally. No visual output on initial paint. -->
87
+ <ul class="nav nav-tabs d-none" id="mainTabs" role="tablist" aria-hidden="true">
88
+ <li class="nav-item"><button class="nav-link active" id="dashboard-tab" data-bs-toggle="tab" data-bs-target="#dashboard-pane" type="button"></button></li>
89
+ <li class="nav-item"><button class="nav-link" id="graph-tab" data-bs-toggle="tab" data-bs-target="#graph-pane" type="button"></button></li>
90
+ <li class="nav-item"><button class="nav-link" id="memories-tab" data-bs-toggle="tab" data-bs-target="#memories-pane" type="button"></button></li>
91
+ <li class="nav-item"><button class="nav-link" id="recall-lab-tab" data-bs-toggle="tab" data-bs-target="#recall-lab-pane" type="button"></button></li>
92
+ <li class="nav-item"><button class="nav-link" id="clusters-tab" data-bs-toggle="tab" data-bs-target="#clusters-pane" type="button"></button></li>
93
+ <li class="nav-item"><button class="nav-link" id="timeline-tab" data-bs-toggle="tab" data-bs-target="#timeline-pane" type="button"></button></li>
94
+ <li class="nav-item"><button class="nav-link" id="brain-tab" data-bs-toggle="tab" data-bs-target="#brain-pane" type="button" role="tab" aria-controls="brain-pane"></button></li>
95
+ <li class="nav-item"><button class="nav-link" id="events-tab" data-bs-toggle="tab" data-bs-target="#events-pane" type="button"></button></li>
96
+ <li class="nav-item"><button class="nav-link" id="agents-tab" data-bs-toggle="tab" data-bs-target="#agents-pane" type="button"></button></li>
97
+ <li class="nav-item"><button class="nav-link" id="trust-tab" data-bs-toggle="tab" data-bs-target="#trust-pane" type="button"></button></li>
98
+ <li class="nav-item"><button class="nav-link" id="lifecycle-tab" data-bs-toggle="tab" data-bs-target="#lifecycle-pane" type="button"></button></li>
99
+ <li class="nav-item"><button class="nav-link" id="compliance-tab" data-bs-toggle="tab" data-bs-target="#compliance-pane" type="button"></button></li>
100
+ <li class="nav-item"><button class="nav-link" id="math-health-tab" data-bs-toggle="tab" data-bs-target="#math-health-pane" type="button"></button></li>
101
+ <li class="nav-item"><button class="nav-link" id="ide-tab" data-bs-toggle="tab" data-bs-target="#ide-pane" type="button"></button></li>
102
+ <li class="nav-item"><button class="nav-link" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings-pane" type="button"></button></li>
806
103
  </ul>
807
104
 
808
105
  <!-- Privacy Notice & Feedback Progress (v2.7.4) -->
@@ -1076,110 +373,176 @@
1076
373
 
1077
374
  <!-- Skip link for keyboard users -->
1078
375
  <a href="#memories-pane" class="visually-hidden-focusable">Skip to Memories list</a>
1079
- </div>
1080
376
 
1081
- <!-- Memories List -->
1082
- <div class="tab-pane fade" id="memories-pane">
1083
- <div class="card p-3 mb-3">
1084
- <div class="row g-2">
1085
- <div class="col-md-5">
1086
- <input type="text" class="form-control search-box" id="search-query" placeholder="Search memories...">
1087
- </div>
1088
- <div class="col-md-2">
1089
- <select class="form-select" id="filter-category">
1090
- <option value="">All Categories</option>
377
+ <!-- Domain 3 (v3.4.21): Clusters folded into Graph. Entity
378
+ Explorer was promoted back out to its own sidebar entry
379
+ under System (v3.4.21c) so it's independently reachable. -->
380
+ <div class="card p-3 mt-3">
381
+ <div class="d-flex justify-content-between align-items-center mb-3">
382
+ <h5 class="mb-0"><i class="bi bi-collection"></i> Knowledge Clusters</h5>
383
+ <button class="btn btn-sm btn-outline-secondary" onclick="loadClusters()" title="Refresh clusters">
384
+ <i class="bi bi-arrow-clockwise"></i>
385
+ </button>
386
+ </div>
387
+ <div class="d-flex justify-content-between align-items-center mb-2 flex-wrap gap-2">
388
+ <div class="d-flex align-items-center gap-2">
389
+ <label class="small text-muted mb-0">Sort</label>
390
+ <select class="form-select form-select-sm" id="clusters-sort" style="width: auto;">
391
+ <option value="members-desc" selected>Member count (high \u2192 low)</option>
392
+ <option value="members-asc">Member count (low \u2192 high)</option>
393
+ <option value="recent-desc">Most recent</option>
1091
394
  </select>
1092
- </div>
1093
- <div class="col-md-2">
1094
- <select class="form-select" id="filter-project">
1095
- <option value="">All Projects</option>
395
+ <label class="small text-muted mb-0 ms-2">Show</label>
396
+ <select class="form-select form-select-sm" id="clusters-page-size" style="width: auto;">
397
+ <option value="10">10</option>
398
+ <option value="25" selected>25</option>
399
+ <option value="50">50</option>
400
+ <option value="100">100</option>
1096
401
  </select>
1097
402
  </div>
1098
- <div class="col-md-1">
1099
- <button class="btn btn-primary w-100" onclick="searchMemories()" title="Search">
1100
- <i class="bi bi-search"></i>
1101
- </button>
1102
- </div>
1103
- <div class="col-md-2">
1104
- <div class="dropdown export-dropdown">
1105
- <button class="btn btn-outline-secondary w-100 dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
1106
- <i class="bi bi-download"></i> Export
1107
- </button>
1108
- <ul class="dropdown-menu">
1109
- <li><a class="dropdown-item" href="#" onclick="exportAll('json'); return false;">
1110
- <i class="bi bi-filetype-json"></i> Export All (JSON)
1111
- </a></li>
1112
- <li><a class="dropdown-item" href="#" onclick="exportAll('jsonl'); return false;">
1113
- <i class="bi bi-file-text"></i> Export All (JSONL)
1114
- </a></li>
1115
- <li><hr class="dropdown-divider"></li>
1116
- <li><a class="dropdown-item" href="#" id="export-search-btn" onclick="exportSearchResults(); return false;" style="display:none;">
1117
- <i class="bi bi-funnel"></i> Export Search Results
1118
- </a></li>
1119
- </ul>
1120
- </div>
1121
- </div>
403
+ <div class="small text-muted" id="clusters-page-info">&mdash;</div>
1122
404
  </div>
1123
- </div>
1124
- <div class="card p-3">
1125
- <div id="memories-list" class="table-responsive">
405
+ <div id="clusters-list">
1126
406
  <div class="loading">
1127
407
  <div class="spinner-border text-primary" role="status"></div>
1128
- <div>Loading memories...</div>
408
+ <div>Loading clusters...</div>
1129
409
  </div>
1130
410
  </div>
411
+ <nav class="d-flex justify-content-between align-items-center mt-2" aria-label="Clusters pagination">
412
+ <button class="btn btn-sm btn-outline-secondary" id="clusters-prev-btn" type="button">
413
+ <i class="bi bi-chevron-left"></i> Prev
414
+ </button>
415
+ <span class="small text-muted" id="clusters-page-detail">Page &mdash;</span>
416
+ <button class="btn btn-sm btn-outline-secondary" id="clusters-next-btn" type="button">
417
+ Next <i class="bi bi-chevron-right"></i>
418
+ </button>
419
+ </nav>
1131
420
  </div>
1132
421
  </div>
1133
422
 
1134
- <!-- V3 Recall Lab -->
1135
- <div class="tab-pane fade" id="recall-lab-pane">
1136
- <h5>Recall Lab Search with Channel Breakdown</h5>
1137
- <p class="text-muted">See how each retrieval channel contributes to results.</p>
1138
- <div class="input-group mb-3">
1139
- <input type="text" id="recall-lab-query" class="form-control form-control-lg" placeholder="Enter your query...">
1140
- <select id="recall-lab-per-page" class="form-select" style="max-width:100px;">
1141
- <option value="10" selected>10</option>
1142
- <option value="25">25</option>
1143
- <option value="50">50</option>
1144
- </select>
1145
- <button class="btn btn-primary btn-lg" id="recall-lab-search">
1146
- <i class="bi bi-search"></i> Search
423
+ <!-- Entity Explorer standalone pane (v3.4.21c).
424
+ Broken out of Graph per Varun's taxonomy: entities stand
425
+ independently as a first-class concern. Same DOM IDs as the
426
+ previous embedded version so ng-entities.js keeps working. -->
427
+ <div class="tab-pane fade" id="entities-pane">
428
+ <div class="d-flex justify-content-between align-items-center mb-3">
429
+ <div>
430
+ <h3 class="mb-0"><i class="bi bi-person-badge"></i> Entity Explorer</h3>
431
+ <small class="text-muted">Compiled truth per entity &mdash; PageRank + Louvain communities</small>
432
+ </div>
433
+ <button class="btn btn-sm btn-outline-secondary" onclick="loadEntityExplorer()" title="Refresh entities">
434
+ <i class="bi bi-arrow-clockwise"></i> Refresh
1147
435
  </button>
1148
436
  </div>
1149
- <div id="recall-lab-meta" class="mb-3 text-muted small"></div>
1150
- <div id="recall-lab-results"></div>
437
+ <div id="entities-list" class="card p-3">
438
+ <div class="loading">
439
+ <div class="spinner-border text-primary" role="status"></div>
440
+ <div>Loading entities...</div>
441
+ </div>
442
+ </div>
443
+ <div id="entity-detail-panel" class="mt-3" style="display:none"></div>
1151
444
  </div>
1152
445
 
1153
- <!-- Clusters -->
1154
- <div class="tab-pane fade" id="clusters-pane">
1155
- <div class="card p-3">
1156
- <h5 class="mb-3">Knowledge Clusters</h5>
1157
- <div id="clusters-list">
1158
- <div class="loading">
1159
- <div class="spinner-border text-primary" role="status"></div>
1160
- <div>Loading clusters...</div>
1161
- </div>
446
+ <!-- Memories List -->
447
+ <div class="tab-pane fade" id="memories-pane">
448
+ <!-- Domain 4 (v3.4.21): Recall Lab is the primary search at
449
+ the top — it returns per-channel score breakdowns so
450
+ you can see exactly which retrieval channel contributed.
451
+ Below that, "Browse all memories" is a filtered list
452
+ view (category + project + export) without its own
453
+ text search — we don't want two search inputs in one
454
+ pane. ``#search-query`` is kept as a hidden input
455
+ because init.js still wires an Enter-key handler to
456
+ it; that legacy file is slated for deletion in the
457
+ final dead-code purge. -->
458
+ <div class="card p-3 mb-3">
459
+ <h5 class="mb-2"><i class="bi bi-search-heart"></i> Search memories</h5>
460
+ <p class="text-muted small mb-3">Per-channel score breakdown — see exactly which retrieval channel contributed to each result.</p>
461
+ <div class="input-group mb-3">
462
+ <input type="text" id="recall-lab-query" class="form-control form-control-lg" placeholder="Type a query...">
463
+ <select id="recall-lab-per-page" class="form-select" style="max-width:110px;" aria-label="Results per page">
464
+ <option value="10" selected>10 / page</option>
465
+ <option value="25">25 / page</option>
466
+ <option value="50">50 / page</option>
467
+ </select>
468
+ <button class="btn btn-primary btn-lg" id="recall-lab-search">
469
+ <i class="bi bi-search"></i> Search
470
+ </button>
1162
471
  </div>
472
+ <div id="recall-lab-meta" class="mb-3 text-muted small"></div>
473
+ <div id="recall-lab-results"></div>
1163
474
  </div>
1164
- </div>
1165
475
 
1166
- <!-- Patterns -->
1167
- <div class="tab-pane fade" id="patterns-pane">
1168
- <div class="card p-3">
1169
- <h5 class="mb-3">Learned Patterns</h5>
1170
- <div id="patterns-list">
476
+ <input type="hidden" id="search-query" value="" aria-hidden="true">
477
+
478
+ <div class="card p-3 mb-3">
479
+ <div class="d-flex justify-content-between align-items-center mb-3">
480
+ <h5 class="mb-0"><i class="bi bi-list-ul"></i> Browse all memories</h5>
481
+ <div class="dropdown export-dropdown">
482
+ <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
483
+ <i class="bi bi-download"></i> Export
484
+ </button>
485
+ <ul class="dropdown-menu dropdown-menu-end">
486
+ <li><a class="dropdown-item" href="#" onclick="exportAll('json'); return false;">
487
+ <i class="bi bi-filetype-json"></i> Export All (JSON)
488
+ </a></li>
489
+ <li><a class="dropdown-item" href="#" onclick="exportAll('jsonl'); return false;">
490
+ <i class="bi bi-file-text"></i> Export All (JSONL)
491
+ </a></li>
492
+ <li><hr class="dropdown-divider"></li>
493
+ <li><a class="dropdown-item" href="#" id="export-search-btn" onclick="exportSearchResults(); return false;" style="display:none;">
494
+ <i class="bi bi-funnel"></i> Export Search Results
495
+ </a></li>
496
+ </ul>
497
+ </div>
498
+ </div>
499
+ <div class="row g-2 mb-3">
500
+ <div class="col-md-5">
501
+ <select class="form-select" id="filter-category" onchange="searchMemories()">
502
+ <option value="">All categories</option>
503
+ </select>
504
+ </div>
505
+ <div class="col-md-5">
506
+ <select class="form-select" id="filter-project" onchange="searchMemories()">
507
+ <option value="">All projects</option>
508
+ </select>
509
+ </div>
510
+ <div class="col-md-2">
511
+ <button class="btn btn-outline-secondary w-100" onclick="searchMemories()" title="Refresh list">
512
+ <i class="bi bi-arrow-clockwise"></i> Refresh
513
+ </button>
514
+ </div>
515
+ </div>
516
+ <!-- S9-DASH-07: learning-visibility filter pills -->
517
+ <div class="row g-2 mb-3">
518
+ <div class="col-12">
519
+ <span class="text-muted small me-2">Learning lens:</span>
520
+ <button type="button"
521
+ class="btn btn-sm btn-outline-success mem-filter-pill"
522
+ data-filter="high_reward"
523
+ onclick="setMemoryFilter('high_reward')"
524
+ title="Facts with reward ≥ 0.7 in last 30 days">
525
+ ⭐ High-reward (30d)
526
+ </button>
527
+ <button type="button"
528
+ class="btn btn-sm btn-outline-warning mem-filter-pill ms-2"
529
+ data-filter="being_forgotten"
530
+ onclick="setMemoryFilter('being_forgotten')"
531
+ title="Archived or cold with no positive reward in 60 days">
532
+ 🕯️ Being forgotten
533
+ </button>
534
+ </div>
535
+ </div>
536
+ <div id="memories-list" class="table-responsive">
1171
537
  <div class="loading">
1172
538
  <div class="spinner-border text-primary" role="status"></div>
1173
- <div>Loading patterns...</div>
539
+ <div>Loading memories...</div>
1174
540
  </div>
1175
541
  </div>
1176
542
  </div>
1177
- </div>
1178
543
 
1179
- <!-- Timeline -->
1180
- <div class="tab-pane fade" id="timeline-pane">
1181
- <div class="card p-3">
1182
- <h5 class="mb-3">Memory Creation Timeline</h5>
544
+ <div class="card p-3 mt-3">
545
+ <h5 class="mb-3"><i class="bi bi-clock-history"></i> Memory creation timeline</h5>
1183
546
  <div id="timeline-chart" class="timeline-chart">
1184
547
  <div class="loading">
1185
548
  <div class="spinner-border text-primary" role="status"></div>
@@ -1189,542 +552,313 @@
1189
552
  </div>
1190
553
  </div>
1191
554
 
1192
- <!-- Learning System -->
1193
- <div class="tab-pane fade" id="learning-pane">
1194
- <!-- Getting Started Guide -->
1195
- <div class="alert alert-light border mb-3" id="learning-getting-started">
1196
- <h6 class="mb-2"><i class="bi bi-info-circle text-primary"></i> How Learning Works</h6>
1197
- <p class="mb-1 small">SuperLocalMemory learns from your usage patterns to improve retrieval ranking over time. This happens automatically as you use <code>slm recall</code> or search via MCP.</p>
1198
- <ul class="small mb-0">
1199
- <li><strong>0-20 signals:</strong> Baseline phase (collecting data)</li>
1200
- <li><strong>20+ signals:</strong> Rule-based ranking adjustments</li>
1201
- <li><strong>200+ signals:</strong> ML model trained on your patterns</li>
1202
- </ul>
1203
- <p class="mb-0 mt-1 small text-muted">Each recall query generates a signal. Keep using SLM and this tab will populate automatically.</p>
555
+ <!-- Brain (v3.4.21 Living Brain Activation — unified Brain panel) -->
556
+ <div class="tab-pane fade" id="brain-pane" role="tabpanel" aria-labelledby="brain-tab">
557
+ <div class="brain-header mb-3">
558
+ <h3 class="mb-0"><i class="bi bi-lightbulb"></i> Brain</h3>
1204
559
  </div>
1205
- <!-- Ranking Phase & Engagement -->
1206
- <div class="row g-3 mb-3">
1207
- <div class="col-md-4">
1208
- <div class="card p-3 text-center">
1209
- <div class="fw-bold text-muted small">RANKING PHASE</div>
1210
- <div class="fs-3 fw-bold" id="learning-phase" style="color: var(--bs-primary);">--</div>
1211
- <small class="text-muted" id="learning-phase-detail">Loading...</small>
1212
- </div>
1213
- </div>
1214
- <div class="col-md-4">
1215
- <div class="card p-3 text-center">
1216
- <div class="fw-bold text-muted small">FEEDBACK SIGNALS</div>
1217
- <div class="fs-3 fw-bold" id="learning-feedback-count">0</div>
1218
- <small class="text-muted" id="learning-feedback-detail">0 unique queries</small>
1219
- </div>
1220
- </div>
1221
- <div class="col-md-4">
1222
- <div class="card p-3 text-center">
1223
- <div class="fw-bold text-muted small">ENGAGEMENT HEALTH</div>
1224
- <div class="fs-3 fw-bold" id="learning-health" style="color: var(--bs-success);">--</div>
1225
- <small class="text-muted" id="learning-health-detail">Loading...</small>
1226
- </div>
1227
- </div>
560
+ <div id="brain-content" aria-live="polite">
561
+ <div class="spinner-border text-primary" role="status" aria-label="Loading"></div>
562
+ <span class="text-muted ms-2">Loading Brain...</span>
1228
563
  </div>
564
+ </div>
1229
565
 
1230
- <!-- Phase Progress Bar -->
1231
- <div class="card p-3 mb-3">
1232
- <h6 class="mb-2"><i class="bi bi-bar-chart-steps"></i> Adaptive Ranking Progress</h6>
1233
- <div class="d-flex align-items-center gap-2 mb-2">
1234
- <div class="flex-grow-1">
1235
- <div class="progress" style="height: 24px; border-radius: 12px;">
1236
- <div class="progress-bar" id="learning-progress" role="progressbar" style="width: 0%; border-radius: 12px; transition: width 0.8s ease;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
1237
- </div>
1238
- </div>
1239
- </div>
1240
- </div>
1241
- <div class="d-flex justify-content-between small text-muted">
1242
- <span>Baseline (0)</span>
1243
- <span>Rule-Based (20+)</span>
1244
- <span>ML Model (200+)</span>
1245
- </div>
1246
- </div>
566
+ <!-- Live Events (v2.5) -->
1247
567
 
1248
- <!-- What We Learned (v2.7.4 — Summary Card) -->
1249
- <div class="card p-3 mb-3" id="what-we-learned-card">
1250
- <div class="d-flex justify-content-between align-items-center mb-3">
1251
- <h6 class="mb-0"><i class="bi bi-lightbulb"></i> What SuperLocalMemory Learned About You</h6>
1252
- <span class="badge bg-success" id="learned-profile-badge">default</span>
1253
- </div>
1254
- <div id="what-we-learned-content">
1255
- <div class="text-center text-muted py-3">
1256
- <i class="bi bi-hourglass-split" style="font-size: 1.5rem;"></i>
1257
- <p class="mt-2 mb-0 small">Loading learned insights...</p>
1258
- </div>
1259
- </div>
1260
- </div>
1261
568
 
1262
- <div class="row g-3">
1263
- <!-- Tech Preferences (Layer 1) -->
1264
- <div class="col-md-6">
1265
- <div class="card p-3 h-100">
1266
- <div class="d-flex justify-content-between align-items-center mb-3">
1267
- <h6 class="mb-0"><i class="bi bi-cpu"></i> Tech Preferences</h6>
1268
- <span class="badge bg-primary">Layer 1</span>
1269
- </div>
1270
- <div id="learning-tech-prefs">
1271
- <div class="text-center text-muted py-3">
1272
- <i class="bi bi-hourglass-split" style="font-size: 1.5rem;"></i>
1273
- <p class="mt-2 mb-0 small">Patterns detected after using recall with feedback</p>
1274
- </div>
1275
- </div>
1276
- </div>
1277
- </div>
1278
569
 
1279
- <!-- Workflow Patterns (Layer 3) -->
1280
- <div class="col-md-6">
1281
- <div class="card p-3 h-100">
1282
- <div class="d-flex justify-content-between align-items-center mb-3">
1283
- <h6 class="mb-0"><i class="bi bi-diagram-3"></i> Workflow Patterns</h6>
1284
- <span class="badge bg-info">Layer 3</span>
1285
- </div>
1286
- <div id="learning-workflows">
1287
- <div class="text-center text-muted py-3">
1288
- <i class="bi bi-hourglass-split" style="font-size: 1.5rem;"></i>
1289
- <p class="mt-2 mb-0 small">Sequences detected after 30+ memories</p>
1290
- </div>
1291
- </div>
1292
- </div>
570
+ <!-- Health Domain 5 unified pane (v3.4.21).
571
+ Absorbed: Live Events, Connected Agents, Ingestion Status,
572
+ Memory Lifecycle, Math Health, Trust, Compliance.
573
+ All original DOM IDs preserved so every loader function
574
+ (loadHealthMonitor, loadAgents, loadTrustDashboard, etc.)
575
+ keeps working without modification. -->
576
+ <div class="tab-pane fade" id="health-pane">
577
+ <div class="d-flex justify-content-between align-items-center mb-3">
578
+ <h3 class="mb-0"><i class="bi bi-heart-pulse"></i> Health &amp; Operations</h3>
579
+ </div>
580
+
581
+ <!-- Sub-nav: scroll-only. Health covers runtime/system
582
+ health only. Governance concerns (Ingestion,
583
+ Lifecycle, Trust, Compliance) live in a separate
584
+ Operations pane. -->
585
+ <div class="card p-2 mb-3" id="health-subnav">
586
+ <div class="d-flex flex-wrap gap-1 small">
587
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-daemon').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-heart-pulse"></i> Daemon</button>
588
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-events').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-broadcast"></i> Events</button>
589
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-agents').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-robot"></i> Agents</button>
590
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-ides').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-plug"></i> IDEs</button>
591
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-math').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-calculator"></i> Math</button>
1293
592
  </div>
1294
593
  </div>
1295
594
 
1296
- <div class="row g-3 mt-0">
1297
- <!-- Source Quality -->
1298
- <div class="col-md-6">
1299
- <div class="card p-3 h-100">
1300
- <div class="d-flex justify-content-between align-items-center mb-3">
1301
- <h6 class="mb-0"><i class="bi bi-stars"></i> Source Quality</h6>
1302
- <span class="badge bg-success">Per-Tool Scoring</span>
1303
- </div>
1304
- <div id="learning-sources">
1305
- <div class="text-center text-muted py-3">
1306
- <i class="bi bi-hourglass-split" style="font-size: 1.5rem;"></i>
1307
- <p class="mt-2 mb-0 small">Quality scores computed after feedback signals</p>
595
+ <!-- ===== SECTION: Daemon health ===== -->
596
+ <section id="health-section-daemon" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
597
+ <div class="d-flex justify-content-between align-items-center mb-3">
598
+ <h5 class="mb-0"><i class="bi bi-heart-pulse"></i> Daemon health</h5>
599
+ <button class="btn btn-sm btn-outline-secondary" onclick="loadHealthMonitor()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
600
+ </div>
601
+ <div id="health-overview"></div>
602
+ <div class="row g-3">
603
+ <div class="col-lg-8">
604
+ <h6 class="mb-2"><i class="bi bi-cpu"></i> Worker Processes</h6>
605
+ <div id="health-processes">
606
+ <div class="text-center py-3 text-muted">
607
+ <div class="spinner-border spinner-border-sm"></div>
608
+ <div class="mt-1 small">Loading processes...</div>
1308
609
  </div>
1309
610
  </div>
1310
611
  </div>
1311
- </div>
1312
-
1313
- <!-- Engagement & Privacy -->
1314
- <div class="col-md-6">
1315
- <div class="card p-3 h-100">
1316
- <div class="d-flex justify-content-between align-items-center mb-3">
1317
- <h6 class="mb-0"><i class="bi bi-shield-lock"></i> Privacy & Data</h6>
1318
- <span class="badge bg-secondary">GDPR Compliant</span>
1319
- </div>
1320
- <div id="learning-privacy">
1321
- <div class="small">
1322
- <div class="d-flex justify-content-between border-bottom py-1">
1323
- <span class="text-muted">Learning DB</span>
1324
- <span class="fw-bold" id="learning-db-size">--</span>
1325
- </div>
1326
- <div class="d-flex justify-content-between border-bottom py-1">
1327
- <span class="text-muted">Patterns learned</span>
1328
- <span class="fw-bold" id="learning-pattern-count">0</span>
1329
- </div>
1330
- <div class="d-flex justify-content-between border-bottom py-1">
1331
- <span class="text-muted">Models trained</span>
1332
- <span class="fw-bold" id="learning-model-count">0</span>
1333
- </div>
1334
- <div class="d-flex justify-content-between border-bottom py-1">
1335
- <span class="text-muted">Sources tracked</span>
1336
- <span class="fw-bold" id="learning-source-count">0</span>
1337
- </div>
1338
- <div class="d-flex justify-content-between py-1">
1339
- <span class="text-muted">Telemetry</span>
1340
- <span class="text-success fw-bold">None</span>
1341
- </div>
1342
- </div>
1343
- <div class="mt-2">
1344
- <button class="btn btn-sm btn-outline-danger" onclick="resetLearning()">
1345
- <i class="bi bi-trash"></i> Reset Learning Data
1346
- </button>
1347
- <small class="text-muted d-block mt-1">Deletes learning.db. Memories preserved.</small>
1348
- </div>
612
+ <div class="col-lg-4">
613
+ <h6 class="mb-2"><i class="bi bi-sliders"></i> Budget Rules</h6>
614
+ <div id="health-budget-rules">
615
+ <div class="text-muted small">Loading...</div>
1349
616
  </div>
1350
617
  </div>
1351
618
  </div>
1352
- </div>
1353
- </div>
619
+ </section>
1354
620
 
1355
- <!-- Live Events (v2.5) -->
1356
- <div class="tab-pane fade" id="events-pane">
1357
- <div class="card p-3 mb-3">
1358
- <div class="row align-items-center mb-3">
1359
- <div class="col-md-6">
1360
- <h5 class="mb-0"><i class="bi bi-broadcast"></i> Live Event Stream</h5>
621
+ <!-- ===== SECTION: Live events ===== -->
622
+ <section id="health-section-events" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
623
+ <div class="d-flex justify-content-between align-items-center mb-3">
624
+ <div>
625
+ <h5 class="mb-0"><i class="bi bi-broadcast"></i> Live event stream</h5>
1361
626
  <small class="text-muted">Real-time memory operations as they happen</small>
1362
627
  </div>
1363
- <div class="col-md-6 text-end">
628
+ <div>
1364
629
  <span id="event-connection-status" class="badge bg-secondary me-2">Connecting...</span>
1365
630
  <select class="form-select form-select-sm d-inline-block w-auto" id="event-type-filter" onchange="filterEvents()">
1366
- <option value="">All Events</option>
1367
- <option value="memory.created">Memory Created</option>
1368
- <option value="memory.updated">Memory Updated</option>
1369
- <option value="memory.deleted">Memory Deleted</option>
1370
- <option value="memory.recalled">Memory Recalled</option>
1371
- <option value="agent.connected">Agent Connected</option>
631
+ <option value="">All events</option>
632
+ <option value="memory.created">Memory created</option>
633
+ <option value="memory.updated">Memory updated</option>
634
+ <option value="memory.deleted">Memory deleted</option>
635
+ <option value="memory.recalled">Memory recalled</option>
636
+ <option value="agent.connected">Agent connected</option>
1372
637
  </select>
1373
638
  <button class="btn btn-sm btn-outline-secondary ms-1" onclick="clearEventStream()">
1374
639
  <i class="bi bi-trash"></i> Clear
1375
640
  </button>
1376
641
  </div>
1377
642
  </div>
1378
- <!-- Event Stats Row -->
1379
643
  <div class="row g-2 mb-3" id="event-stats-row">
1380
- <div class="col-md-3">
1381
- <div class="border rounded p-2 text-center">
1382
- <div class="fw-bold" id="event-stat-total">0</div>
1383
- <small class="text-muted">Total Events</small>
1384
- </div>
1385
- </div>
1386
- <div class="col-md-3">
1387
- <div class="border rounded p-2 text-center">
1388
- <div class="fw-bold" id="event-stat-24h">0</div>
1389
- <small class="text-muted">Last 24h</small>
1390
- </div>
1391
- </div>
1392
- <div class="col-md-3">
1393
- <div class="border rounded p-2 text-center">
1394
- <div class="fw-bold" id="event-stat-listeners">0</div>
1395
- <small class="text-muted">Listeners</small>
1396
- </div>
1397
- </div>
1398
- <div class="col-md-3">
1399
- <div class="border rounded p-2 text-center">
1400
- <div class="fw-bold" id="event-stat-buffer">0</div>
1401
- <small class="text-muted">In Buffer</small>
1402
- </div>
1403
- </div>
644
+ <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="event-stat-total">0</div><small class="text-muted">Total events</small></div></div>
645
+ <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="event-stat-24h">0</div><small class="text-muted">Last 24h</small></div></div>
646
+ <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="event-stat-listeners">0</div><small class="text-muted">Listeners</small></div></div>
647
+ <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="event-stat-buffer">0</div><small class="text-muted">In buffer</small></div></div>
1404
648
  </div>
1405
- <!-- Event Stream -->
1406
- <div id="event-stream" style="max-height: 500px; overflow-y: auto; font-family: 'Courier New', monospace; font-size: 0.85rem; background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); border-radius: 8px; padding: 12px;">
649
+ <div id="event-stream" style="max-height: 400px; overflow-y: auto; font-family: 'SF Mono', Consolas, monospace; font-size: 0.85rem; background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); border-radius: 8px; padding: 12px;">
1407
650
  <div class="text-muted text-center py-4">
1408
651
  <i class="bi bi-broadcast" style="font-size: 2rem;"></i>
1409
- <p class="mt-2">Waiting for events...</p>
1410
- <small>Events will appear here in real-time as memories are created, updated, or deleted.</small>
652
+ <p class="mt-2 mb-0">Waiting for events...</p>
653
+ <small>Events appear here in real-time as memories are created, updated, or deleted.</small>
1411
654
  </div>
1412
655
  </div>
1413
- </div>
1414
- </div>
656
+ </section>
1415
657
 
1416
- <!-- Connected Agents (v2.5) -->
1417
- <div class="tab-pane fade" id="agents-pane">
1418
- <div class="card p-3 mb-3">
1419
- <div class="row align-items-center mb-3">
1420
- <div class="col-md-6">
1421
- <h5 class="mb-0"><i class="bi bi-robot"></i> Connected Agents</h5>
658
+ <!-- ===== SECTION: Agents ===== -->
659
+ <section id="health-section-agents" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
660
+ <div class="d-flex justify-content-between align-items-center mb-3">
661
+ <div>
662
+ <h5 class="mb-0"><i class="bi bi-robot"></i> Connected agents</h5>
1422
663
  <small class="text-muted">AI tools that interact with your memory</small>
1423
664
  </div>
1424
- <div class="col-md-6 text-end">
1425
- <button class="btn btn-sm btn-outline-primary" onclick="loadAgents()">
1426
- <i class="bi bi-arrow-clockwise"></i> Refresh
1427
- </button>
1428
- </div>
665
+ <button class="btn btn-sm btn-outline-secondary" onclick="loadAgents()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
1429
666
  </div>
1430
- <!-- Agent Stats -->
1431
667
  <div class="row g-2 mb-3" id="agent-stats-row">
1432
- <div class="col-md-3">
1433
- <div class="border rounded p-2 text-center">
1434
- <div class="fw-bold" id="agent-stat-total">0</div>
1435
- <small class="text-muted">Total Agents</small>
1436
- </div>
1437
- </div>
1438
- <div class="col-md-3">
1439
- <div class="border rounded p-2 text-center">
1440
- <div class="fw-bold" id="agent-stat-active">0</div>
1441
- <small class="text-muted">Active (24h)</small>
1442
- </div>
1443
- </div>
1444
- <div class="col-md-3">
1445
- <div class="border rounded p-2 text-center">
1446
- <div class="fw-bold" id="agent-stat-writes">0</div>
1447
- <small class="text-muted">Total Writes</small>
1448
- </div>
1449
- </div>
1450
- <div class="col-md-3">
1451
- <div class="border rounded p-2 text-center">
1452
- <div class="fw-bold" id="agent-stat-recalls">0</div>
1453
- <small class="text-muted">Total Recalls</small>
1454
- </div>
1455
- </div>
668
+ <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="agent-stat-total">0</div><small class="text-muted">Total agents</small></div></div>
669
+ <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="agent-stat-active">0</div><small class="text-muted">Active (24h)</small></div></div>
670
+ <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="agent-stat-writes">0</div><small class="text-muted">Total writes</small></div></div>
671
+ <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="agent-stat-recalls">0</div><small class="text-muted">Total recalls</small></div></div>
1456
672
  </div>
1457
- <!-- Agent List -->
1458
673
  <div id="agents-list" class="table-responsive">
1459
674
  <div class="loading">
1460
675
  <div class="spinner-border text-primary" role="status"></div>
1461
676
  <div>Loading agents...</div>
1462
677
  </div>
1463
678
  </div>
1464
- </div>
1465
- <!-- Trust Overview -->
1466
- <div class="card p-3">
1467
- <h5 class="mb-3"><i class="bi bi-shield-check"></i> Trust Scoring <span class="badge bg-info">Silent Collection</span></h5>
1468
- <p class="text-muted small mb-3">Trust scores are being collected silently. No enforcement in v2.5 — scores will affect recall ranking in v2.6.</p>
1469
- <div id="trust-overview">
1470
- <div class="loading">
1471
- <div class="spinner-border text-primary" role="status"></div>
1472
- <div>Loading trust data...</div>
1473
- </div>
1474
- </div>
1475
- </div>
1476
- </div>
1477
-
1478
- <!-- Trust Dashboard (V3) -->
1479
- <div class="tab-pane fade" id="trust-pane">
1480
- <h5><i class="bi bi-shield-check"></i> Trust Dashboard</h5>
1481
- <p class="text-muted">Bayesian trust scoring per agent and per fact.</p>
1482
- <div class="row g-3 mb-3">
1483
- <div class="col-md-4">
1484
- <div class="card text-center">
1485
- <div class="card-body">
1486
- <h6>Total Agents</h6>
1487
- <h3 id="trust-agent-count">0</h3>
1488
- </div>
1489
- </div>
1490
- </div>
1491
- <div class="col-md-4">
1492
- <div class="card text-center">
1493
- <div class="card-body">
1494
- <h6>Avg Trust Score</h6>
1495
- <h3 id="trust-avg-score">&mdash;</h3>
1496
- </div>
1497
- </div>
1498
- </div>
1499
- <div class="col-md-4">
1500
- <div class="card text-center">
1501
- <div class="card-body">
1502
- <h6>Burst Alerts</h6>
1503
- <h3 id="trust-burst-count" class="text-danger">0</h3>
1504
- </div>
1505
- </div>
1506
- </div>
1507
- </div>
1508
- <div id="trust-agents-table" class="table-responsive">
1509
- <table class="table table-sm table-striped">
1510
- <thead><tr><th>Agent/Fact</th><th>Type</th><th>Trust Score</th><th>Evidence</th><th>Status</th></tr></thead>
1511
- <tbody id="trust-agents-body"></tbody>
1512
- </table>
1513
- </div>
1514
- </div>
1515
-
1516
- <!-- Lifecycle (v2.8) -->
1517
- <div class="tab-pane fade" id="lifecycle-pane" role="tabpanel">
1518
- <div class="d-flex justify-content-between align-items-center mb-3">
1519
- <h5 class="mb-0"><i class="bi bi-hourglass-split text-warning"></i> Memory Lifecycle</h5>
1520
- <div>
1521
- <span class="badge bg-secondary me-2" id="lifecycle-profile-badge">default</span>
1522
- <button class="btn btn-sm btn-outline-success" onclick="evaluateTiersNow()"><i class="bi bi-arrow-repeat"></i> Evaluate Tiers</button>
1523
- <button class="btn btn-sm btn-outline-info ms-1" onclick="compactDryRun()"><i class="bi bi-funnel"></i> Preview Compaction</button>
1524
- <button class="btn btn-sm btn-outline-warning ms-1" onclick="compactExecute()"><i class="bi bi-lightning"></i> Compact Now</button>
1525
- </div>
1526
- </div>
679
+ </section>
1527
680
 
1528
- <!-- State Distribution -->
1529
- <div class="row g-3 mb-4" id="lifecycle-states-row">
1530
- <div class="col-md-2"><div class="card p-3 text-center"><div class="text-success fw-bold fs-3" id="lc-active-count">-</div><small class="text-muted">Active</small></div></div>
1531
- <div class="col-md-2"><div class="card p-3 text-center"><div class="text-warning fw-bold fs-3" id="lc-warm-count">-</div><small class="text-muted">Warm</small></div></div>
1532
- <div class="col-md-2"><div class="card p-3 text-center"><div class="text-info fw-bold fs-3" id="lc-cold-count">-</div><small class="text-muted">Cold</small></div></div>
1533
- <div class="col-md-2"><div class="card p-3 text-center"><div class="text-secondary fw-bold fs-3" id="lc-archived-count">-</div><small class="text-muted">Archived</small></div></div>
1534
- <div class="col-md-2"><div class="card p-3 text-center"><div class="text-danger fw-bold fs-3" id="lc-tombstoned-count">-</div><small class="text-muted">Tombstoned</small></div></div>
1535
- <div class="col-md-2"><div class="card p-3 text-center"><div class="fw-bold fs-3" id="lc-total-count">-</div><small class="text-muted">Total</small></div></div>
1536
- </div>
1537
- <!-- State Progress Bar -->
1538
- <div class="card p-3 mb-4">
1539
- <h6 class="mb-2">State Distribution</h6>
1540
- <div class="progress" style="height: 24px;" id="lifecycle-progress-bar"></div>
1541
- </div>
1542
- <!-- Age Stats -->
1543
- <div class="card p-3 mb-4" id="lifecycle-age-stats">
1544
- <h6 class="mb-2">Average Memory Age by State</h6>
1545
- <div id="lifecycle-age-content"><span class="text-muted">Loading...</span></div>
1546
- </div>
1547
- <!-- Recent Transitions -->
1548
- <div class="card p-3">
1549
- <h6 class="mb-2">Recent Transitions</h6>
1550
- <div id="lifecycle-transitions-content"><span class="text-muted">Loading...</span></div>
1551
- </div>
1552
- <!-- Compaction Results Modal -->
1553
- <div id="compaction-results" class="card p-3 mt-3 d-none">
1554
- <h6 class="mb-2" id="compaction-results-title">Compaction Preview</h6>
1555
- <div id="compaction-results-content"></div>
1556
- </div>
681
+ <!-- ===== SECTION: IDEs (v3.4.21 — moved here from standalone pane) ===== -->
682
+ <section id="health-section-ides" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
683
+ <div class="d-flex justify-content-between align-items-center mb-3">
684
+ <div>
685
+ <h5 class="mb-0"><i class="bi bi-plug"></i> IDE connections</h5>
686
+ <small class="text-muted">Cursor / Antigravity / Copilot / Claude Code integration state</small>
687
+ </div>
688
+ <button class="btn btn-sm btn-primary" id="ide-connect-all-btn"><i class="bi bi-link-45deg"></i> Connect all detected</button>
689
+ </div>
690
+ <div id="ide-list" class="table-responsive">
691
+ <table class="table table-sm">
692
+ <thead><tr><th>IDE</th><th>Installed</th><th>Config path</th><th>Action</th></tr></thead>
693
+ <tbody id="ide-list-body"></tbody>
694
+ </table>
695
+ </div>
696
+ </section>
697
+
698
+ <!-- ===== SECTION: Math Health ===== -->
699
+ <section id="health-section-math" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
700
+ <h5 class="mb-2"><i class="bi bi-calculator"></i> Mathematical layer health</h5>
701
+ <p class="text-muted small mb-3">Status of Fisher-Rao, sheaf cohomology, and Langevin dynamics.</p>
702
+ <div class="row g-3" id="math-health-cards"></div>
703
+ </section>
1557
704
  </div>
1558
705
 
1559
- <!-- Behavioral Learning -->
1560
- <div class="tab-pane fade" id="behavioral-pane" role="tabpanel">
706
+ <!-- Operations Domain 5b unified governance pane (v3.4.21).
707
+ Split out from Health because these are data-governance
708
+ concerns, not runtime health: Ingestion (what flows in),
709
+ Lifecycle (tier transitions / compaction), Trust (per-agent
710
+ Bayesian scoring), Compliance (retention + audit). All
711
+ DOM IDs identical to the previous Health-pane sections so
712
+ the loaders (loadIngestionStatus, loadLifecycle,
713
+ loadTrustDashboard, loadCompliance) keep working. -->
714
+ <div class="tab-pane fade" id="operations-pane">
1561
715
  <div class="d-flex justify-content-between align-items-center mb-3">
1562
- <h5 class="mb-0"><i class="bi bi-lightbulb text-info"></i> Behavioral Learning</h5>
1563
- <span class="badge bg-secondary" id="behavioral-profile-badge">default</span>
1564
- </div>
1565
- <!-- Getting Started Guide -->
1566
- <div class="alert alert-light border mb-3">
1567
- <h6 class="mb-2"><i class="bi bi-info-circle text-primary"></i> How Behavioral Learning Works</h6>
1568
- <p class="mb-1 small">This tab tracks how memories are used in practice — which recalls led to successful outcomes (code written, decisions made, bugs fixed) and which didn't.</p>
1569
- <p class="mb-0 small text-muted">Report outcomes using the form below, or via MCP: <code>report_outcome</code>. Patterns emerge after 10+ outcomes.</p>
1570
- </div>
1571
- <!-- Stats Row -->
1572
- <div class="row g-3 mb-4">
1573
- <div class="col-md-3"><div class="card p-3 text-center"><div class="fw-bold fs-3 text-success" id="bh-success-count">-</div><small class="text-muted">Successes</small></div></div>
1574
- <div class="col-md-3"><div class="card p-3 text-center"><div class="fw-bold fs-3 text-danger" id="bh-failure-count">-</div><small class="text-muted">Failures</small></div></div>
1575
- <div class="col-md-3"><div class="card p-3 text-center"><div class="fw-bold fs-3 text-warning" id="bh-partial-count">-</div><small class="text-muted">Partial</small></div></div>
1576
- <div class="col-md-3"><div class="card p-3 text-center"><div class="fw-bold fs-3 text-info" id="bh-patterns-count">-</div><small class="text-muted">Patterns Learned</small></div></div>
716
+ <h3 class="mb-0"><i class="bi bi-diagram-2"></i> Operations &amp; Governance</h3>
1577
717
  </div>
1578
- <!-- Report Outcome Form -->
1579
- <div class="card p-3 mb-4">
1580
- <h6 class="mb-2"><i class="bi bi-plus-circle"></i> Report Outcome</h6>
1581
- <div class="row g-2">
1582
- <div class="col-md-3"><input type="text" class="form-control form-control-sm" id="bh-memory-ids" placeholder="Memory IDs (comma-separated)"></div>
1583
- <div class="col-md-2"><select class="form-select form-select-sm" id="bh-outcome"><option value="success">Success</option><option value="failure">Failure</option><option value="partial">Partial</option></select></div>
1584
- <div class="col-md-3"><select class="form-select form-select-sm" id="bh-action-type"><option value="code_written">Code Written</option><option value="decision_made">Decision Made</option><option value="debug_resolved">Debug Resolved</option><option value="architecture_chosen">Architecture Chosen</option><option value="other">Other</option></select></div>
1585
- <div class="col-md-3"><input type="text" class="form-control form-control-sm" id="bh-context" placeholder="Context (optional)"></div>
1586
- <div class="col-md-1"><button class="btn btn-sm btn-info w-100" onclick="reportOutcome()"><i class="bi bi-send"></i></button></div>
718
+ <div class="card p-2 mb-3" id="operations-subnav">
719
+ <div class="d-flex flex-wrap gap-1 small">
720
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('ops-section-ingestion').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-cloud-download"></i> Ingestion</button>
721
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('ops-section-lifecycle').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-hourglass-split"></i> Lifecycle</button>
722
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('ops-section-trust').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-shield-check"></i> Trust</button>
723
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('ops-section-compliance').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-shield-lock"></i> Compliance</button>
1587
724
  </div>
1588
725
  </div>
1589
- <!-- Learned Patterns -->
1590
- <div class="card p-3 mb-4">
1591
- <h6 class="mb-2">Learned Patterns</h6>
1592
- <div id="behavioral-patterns-content"><span class="text-muted">Loading...</span></div>
1593
- </div>
1594
- <!-- Cross-Project Transfers -->
1595
- <div class="card p-3 mb-4">
1596
- <h6 class="mb-2">Cross-Project Transfers</h6>
1597
- <div id="behavioral-transfers-content"><span class="text-muted">Loading...</span></div>
1598
- </div>
1599
- <!-- Recent Outcomes -->
1600
- <div class="card p-3">
1601
- <h6 class="mb-2">Recent Outcomes</h6>
1602
- <div id="behavioral-outcomes-content"><span class="text-muted">Loading...</span></div>
1603
- </div>
1604
- </div>
1605
726
 
1606
- <!-- Compliance & Audit -->
1607
- <div class="tab-pane fade" id="compliance-pane" role="tabpanel">
1608
- <div class="d-flex justify-content-between align-items-center mb-3">
1609
- <h5 class="mb-0"><i class="bi bi-shield-lock text-success"></i> Compliance &amp; Audit</h5>
1610
- <span class="badge bg-secondary" id="compliance-profile-badge">default</span>
1611
- </div>
1612
- <!-- Getting Started Guide -->
1613
- <div class="alert alert-light border mb-3">
1614
- <h6 class="mb-2"><i class="bi bi-info-circle text-primary"></i> Compliance Overview</h6>
1615
- <p class="mb-1 small">Set retention policies and access controls for your memories. In Mode A, all data stays on your device — EU AI Act compliant by default.</p>
1616
- <p class="mb-0 small text-muted">Create a retention policy below to start managing memory lifecycle automatically.</p>
1617
- </div>
1618
- <!-- Stats Row -->
1619
- <div class="row g-3 mb-4">
1620
- <div class="col-md-4"><div class="card p-3 text-center"><div class="fw-bold fs-3" id="cp-audit-count">-</div><small class="text-muted">Audit Events</small></div></div>
1621
- <div class="col-md-4"><div class="card p-3 text-center"><div class="fw-bold fs-3" id="cp-retention-count">-</div><small class="text-muted">Retention Policies</small></div></div>
1622
- <div class="col-md-4"><div class="card p-3 text-center"><div class="fw-bold fs-3" id="cp-abac-count">-</div><small class="text-muted">Access Policies</small></div></div>
1623
- </div>
1624
- <!-- Set Retention Policy Form -->
1625
- <div class="card p-3 mb-4">
1626
- <h6 class="mb-2"><i class="bi bi-plus-circle"></i> Create Retention Policy</h6>
1627
- <div class="row g-2">
1628
- <div class="col-md-3"><input type="text" class="form-control form-control-sm" id="cp-policy-name" placeholder="Policy name"></div>
1629
- <div class="col-md-2"><input type="number" class="form-control form-control-sm" id="cp-retention-days" placeholder="Days" value="90"></div>
1630
- <div class="col-md-2"><input type="text" class="form-control form-control-sm" id="cp-category" placeholder="Category (optional)"></div>
1631
- <div class="col-md-2"><select class="form-select form-select-sm" id="cp-action"><option value="archive">Archive</option><option value="tombstone">Tombstone</option><option value="notify">Notify Only</option></select></div>
1632
- <div class="col-md-2"><button class="btn btn-sm btn-success w-100" onclick="createRetentionPolicy()"><i class="bi bi-shield-plus"></i> Create</button></div>
1633
- </div>
1634
- </div>
1635
- <!-- Retention Policies List -->
1636
- <div class="card p-3 mb-4">
1637
- <h6 class="mb-2">Active Retention Policies</h6>
1638
- <div id="compliance-policies-content"><span class="text-muted">Loading...</span></div>
1639
- </div>
1640
- <!-- Audit Trail -->
1641
- <div class="card p-3">
1642
- <div class="d-flex justify-content-between align-items-center mb-2">
1643
- <h6 class="mb-0">Audit Trail</h6>
1644
- <div class="d-flex gap-2">
1645
- <select class="form-select form-select-sm" id="cp-audit-filter" style="width: auto;" onchange="loadCompliance()">
1646
- <option value="">All Events</option>
1647
- <option value="recall">Recall</option>
1648
- <option value="remember">Remember</option>
1649
- <option value="delete">Delete</option>
1650
- <option value="lifecycle_transition">Lifecycle</option>
1651
- <option value="access_denied">Access Denied</option>
1652
- <option value="retention_enforced">Retention</option>
1653
- </select>
727
+ <!-- ===== SECTION: Ingestion ===== -->
728
+ <section id="ops-section-ingestion" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
729
+ <div class="d-flex justify-content-between align-items-center mb-3">
730
+ <div>
731
+ <h5 class="mb-0"><i class="bi bi-cloud-download"></i> Ingestion status</h5>
732
+ <small class="text-muted">Gmail, Calendar, Transcript adapters &mdash; all opt-in</small>
1654
733
  </div>
734
+ <button class="btn btn-sm btn-outline-secondary" onclick="loadIngestionStatus()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
1655
735
  </div>
1656
- <div id="compliance-audit-content"><span class="text-muted">Loading...</span></div>
1657
- </div>
1658
- </div>
1659
-
1660
- <!-- Health Monitor (v3.4.3 — Neural Glass) -->
1661
- <div class="tab-pane fade" id="health-pane">
1662
- <div class="ng-content-header">
1663
- <div>
1664
- <div class="ng-content-title"><i class="bi bi-heart-pulse"></i> Health Monitor</div>
1665
- <div class="ng-content-subtitle">Process health, RSS budget, worker heartbeat — real-time</div>
736
+ <div id="ingestion-overview"></div>
737
+ <div id="ingestion-adapters" class="mb-3"></div>
738
+ <h6 class="mb-2"><i class="bi bi-journal-text"></i> Recent ingestion log</h6>
739
+ <div id="ingestion-log">
740
+ <div class="text-center small text-muted py-3">Loading...</div>
1666
741
  </div>
1667
- <button class="ng-btn" onclick="loadHealthMonitor()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
1668
- </div>
1669
- <div id="health-overview"></div>
1670
- <div class="row g-4">
1671
- <div class="col-lg-8">
1672
- <div class="ng-glass" style="padding:20px">
1673
- <h6 style="margin-bottom:16px"><i class="bi bi-cpu"></i> Worker Processes</h6>
1674
- <div id="health-processes">
1675
- <div class="text-center" style="padding:24px;color:var(--ng-text-tertiary)">
1676
- <div class="spinner-border" style="color:var(--ng-accent)"></div>
1677
- <div style="margin-top:8px">Loading processes...</div>
1678
- </div>
1679
- </div>
742
+ </section>
743
+
744
+ <!-- ===== SECTION: Lifecycle ===== -->
745
+ <section id="ops-section-lifecycle" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
746
+ <div class="d-flex justify-content-between align-items-center mb-3">
747
+ <h5 class="mb-0"><i class="bi bi-hourglass-split text-warning"></i> Memory lifecycle</h5>
748
+ <div>
749
+ <span class="badge bg-secondary me-2" id="lifecycle-profile-badge">default</span>
750
+ <button class="btn btn-sm btn-outline-success" onclick="evaluateTiersNow()"><i class="bi bi-arrow-repeat"></i> Evaluate tiers</button>
751
+ <button class="btn btn-sm btn-outline-info ms-1" onclick="compactDryRun()"><i class="bi bi-funnel"></i> Preview compaction</button>
752
+ <button class="btn btn-sm btn-outline-warning ms-1" onclick="compactExecute()"><i class="bi bi-lightning"></i> Compact now</button>
753
+ </div>
754
+ </div>
755
+ <div class="row g-3 mb-3" id="lifecycle-states-row">
756
+ <div class="col-md-2"><div class="border rounded p-2 text-center"><div class="text-success fw-bold fs-4" id="lc-active-count">-</div><small class="text-muted">Active</small></div></div>
757
+ <div class="col-md-2"><div class="border rounded p-2 text-center"><div class="text-warning fw-bold fs-4" id="lc-warm-count">-</div><small class="text-muted">Warm</small></div></div>
758
+ <div class="col-md-2"><div class="border rounded p-2 text-center"><div class="text-info fw-bold fs-4" id="lc-cold-count">-</div><small class="text-muted">Cold</small></div></div>
759
+ <div class="col-md-2"><div class="border rounded p-2 text-center"><div class="text-secondary fw-bold fs-4" id="lc-archived-count">-</div><small class="text-muted">Archived</small></div></div>
760
+ <div class="col-md-2"><div class="border rounded p-2 text-center"><div class="text-danger fw-bold fs-4" id="lc-tombstoned-count">-</div><small class="text-muted">Tombstoned</small></div></div>
761
+ <div class="col-md-2"><div class="border rounded p-2 text-center"><div class="fw-bold fs-4" id="lc-total-count">-</div><small class="text-muted">Total</small></div></div>
762
+ </div>
763
+ <h6 class="mb-2">State distribution</h6>
764
+ <div class="progress mb-3" style="height: 24px;" id="lifecycle-progress-bar"></div>
765
+ <h6 class="mb-2">Average memory age by state</h6>
766
+ <div class="mb-3" id="lifecycle-age-content"><span class="text-muted">Loading...</span></div>
767
+ <h6 class="mb-2">Recent transitions</h6>
768
+ <div id="lifecycle-transitions-content"><span class="text-muted">Loading...</span></div>
769
+ <div id="compaction-results" class="mt-3 d-none">
770
+ <h6 id="compaction-results-title">Compaction preview</h6>
771
+ <div id="compaction-results-content"></div>
772
+ </div>
773
+ </section>
774
+
775
+ <!-- ===== SECTION: Trust ===== -->
776
+ <section id="ops-section-trust" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
777
+ <h5 class="mb-2"><i class="bi bi-shield-check"></i> Trust</h5>
778
+ <p class="text-muted small mb-3">Bayesian trust scoring per agent and per fact.</p>
779
+ <div class="row g-3 mb-3">
780
+ <div class="col-md-4"><div class="border rounded p-2 text-center"><div class="fw-bold fs-4" id="trust-agent-count">0</div><small class="text-muted">Total agents</small></div></div>
781
+ <div class="col-md-4"><div class="border rounded p-2 text-center"><div class="fw-bold fs-4" id="trust-avg-score">&mdash;</div><small class="text-muted">Avg trust score</small></div></div>
782
+ <div class="col-md-4"><div class="border rounded p-2 text-center"><div class="fw-bold fs-4 text-danger" id="trust-burst-count">0</div><small class="text-muted">Burst alerts</small></div></div>
783
+ </div>
784
+ <div id="trust-overview" class="mb-3">
785
+ <div class="loading">
786
+ <div class="spinner-border spinner-border-sm"></div>
787
+ <div class="small">Loading trust overview...</div>
1680
788
  </div>
1681
789
  </div>
1682
- <div class="col-lg-4">
1683
- <div class="ng-glass" style="padding:20px">
1684
- <h6 style="margin-bottom:16px"><i class="bi bi-sliders"></i> Budget Rules</h6>
1685
- <div id="health-budget-rules">
1686
- <div style="color:var(--ng-text-tertiary);font-size:0.8125rem">Loading...</div>
1687
- </div>
790
+ <div class="d-flex justify-content-between align-items-center mb-2 flex-wrap gap-2">
791
+ <div class="d-flex align-items-center gap-2">
792
+ <label class="small text-muted mb-0">Sort</label>
793
+ <select class="form-select form-select-sm" id="trust-sort" style="width: auto;">
794
+ <option value="score-desc" selected>Trust score (high \u2192 low)</option>
795
+ <option value="score-asc">Trust score (low \u2192 high)</option>
796
+ <option value="evidence-desc">Evidence count (high \u2192 low)</option>
797
+ <option value="updated-desc">Last updated (recent first)</option>
798
+ </select>
799
+ <label class="small text-muted mb-0 ms-2">Show</label>
800
+ <select class="form-select form-select-sm" id="trust-page-size" style="width: auto;">
801
+ <option value="10">10</option>
802
+ <option value="25" selected>25</option>
803
+ <option value="50">50</option>
804
+ <option value="100">100</option>
805
+ </select>
1688
806
  </div>
807
+ <div class="small text-muted" id="trust-page-info">&mdash;</div>
1689
808
  </div>
1690
- </div>
1691
- </div>
809
+ <div id="trust-agents-table" class="table-responsive">
810
+ <table class="table table-sm">
811
+ <thead><tr><th>Agent/Fact</th><th>Type</th><th>Trust score</th><th>Evidence</th><th>Status</th></tr></thead>
812
+ <tbody id="trust-agents-body"></tbody>
813
+ </table>
814
+ </div>
815
+ <nav class="d-flex justify-content-between align-items-center mt-2" aria-label="Trust pagination">
816
+ <button class="btn btn-sm btn-outline-secondary" id="trust-prev-btn" type="button">
817
+ <i class="bi bi-chevron-left"></i> Prev
818
+ </button>
819
+ <span class="small text-muted" id="trust-page-detail">Page &mdash;</span>
820
+ <button class="btn btn-sm btn-outline-secondary" id="trust-next-btn" type="button">
821
+ Next <i class="bi bi-chevron-right"></i>
822
+ </button>
823
+ </nav>
824
+ </section>
1692
825
 
1693
- <!-- Ingestion Status (v3.4.3 Neural Glass) -->
1694
- <div class="tab-pane fade" id="ingestion-pane">
1695
- <div class="ng-content-header">
1696
- <div>
1697
- <div class="ng-content-title"><i class="bi bi-cloud-download"></i> Ingestion Status</div>
1698
- <div class="ng-content-subtitle">Gmail, Calendar, Transcript adapters — all opt-in</div>
826
+ <!-- ===== SECTION: Compliance ===== -->
827
+ <section id="ops-section-compliance" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
828
+ <div class="d-flex justify-content-between align-items-center mb-3">
829
+ <h5 class="mb-0"><i class="bi bi-shield-lock text-success"></i> Compliance &amp; audit</h5>
830
+ <span class="badge bg-secondary" id="compliance-profile-badge">default</span>
1699
831
  </div>
1700
- <button class="ng-btn" onclick="loadIngestionStatus()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
1701
- </div>
1702
- <div id="ingestion-overview"></div>
1703
- <div id="ingestion-adapters" style="margin-bottom:24px"></div>
1704
- <div class="ng-glass" style="padding:20px">
1705
- <h6 style="margin-bottom:16px"><i class="bi bi-journal-text"></i> Recent Ingestion Log</h6>
1706
- <div id="ingestion-log">
1707
- <div style="padding:16px;color:var(--ng-text-tertiary);text-align:center;font-size:0.8125rem">Loading...</div>
832
+ <p class="text-muted small mb-3">Set retention policies and access controls. In Mode A, all data stays on your device &mdash; EU AI Act compliant by default.</p>
833
+ <div class="row g-3 mb-3">
834
+ <div class="col-md-4"><div class="border rounded p-2 text-center"><div class="fw-bold fs-4" id="cp-audit-count">-</div><small class="text-muted">Audit events</small></div></div>
835
+ <div class="col-md-4"><div class="border rounded p-2 text-center"><div class="fw-bold fs-4" id="cp-retention-count">-</div><small class="text-muted">Retention policies</small></div></div>
836
+ <div class="col-md-4"><div class="border rounded p-2 text-center"><div class="fw-bold fs-4" id="cp-abac-count">-</div><small class="text-muted">Access policies</small></div></div>
1708
837
  </div>
1709
- </div>
1710
- </div>
1711
-
1712
- <!-- Entity Explorer (v3.4.3 Neural Glass) -->
1713
- <div class="tab-pane fade" id="entities-pane">
1714
- <div class="ng-content-header">
1715
- <div>
1716
- <div class="ng-content-title"><i class="bi bi-person-badge"></i> Entity Explorer</div>
1717
- <div class="ng-content-subtitle">Compiled truth per entity — PageRank + Louvain communities</div>
838
+ <h6 class="mb-2"><i class="bi bi-plus-circle"></i> Create retention policy</h6>
839
+ <div class="row g-2 mb-3">
840
+ <div class="col-md-3"><input type="text" class="form-control form-control-sm" id="cp-policy-name" placeholder="Policy name"></div>
841
+ <div class="col-md-2"><input type="number" class="form-control form-control-sm" id="cp-retention-days" placeholder="Days" value="90"></div>
842
+ <div class="col-md-2"><input type="text" class="form-control form-control-sm" id="cp-category" placeholder="Category (optional)"></div>
843
+ <div class="col-md-2"><select class="form-select form-select-sm" id="cp-action"><option value="archive">Archive</option><option value="tombstone">Tombstone</option><option value="notify">Notify only</option></select></div>
844
+ <div class="col-md-3"><button class="btn btn-sm btn-success w-100" onclick="createRetentionPolicy()"><i class="bi bi-shield-plus"></i> Create policy</button></div>
1718
845
  </div>
1719
- <button class="ng-btn" onclick="loadEntityExplorer()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
1720
- </div>
1721
- <div id="entities-list">
1722
- <div class="text-center" style="padding:24px;color:var(--ng-text-tertiary)">
1723
- <div class="spinner-border" style="color:var(--ng-accent)"></div>
1724
- <div style="margin-top:8px">Loading entities...</div>
846
+ <h6 class="mb-2">Active retention policies</h6>
847
+ <div class="mb-3" id="compliance-policies-content"><span class="text-muted">Loading...</span></div>
848
+ <div class="d-flex justify-content-between align-items-center mb-2">
849
+ <h6 class="mb-0">Audit trail</h6>
850
+ <select class="form-select form-select-sm" id="cp-audit-filter" style="width: auto;" onchange="loadCompliance()">
851
+ <option value="">All events</option>
852
+ <option value="recall">Recall</option>
853
+ <option value="remember">Remember</option>
854
+ <option value="delete">Delete</option>
855
+ <option value="lifecycle_transition">Lifecycle</option>
856
+ <option value="access_denied">Access denied</option>
857
+ <option value="retention_enforced">Retention</option>
858
+ </select>
1725
859
  </div>
1726
- </div>
1727
- <div id="entity-detail-panel" style="display:none;margin-top:24px"></div>
860
+ <div id="compliance-audit-content"><span class="text-muted">Loading...</span></div>
861
+ </section>
1728
862
  </div>
1729
863
 
1730
864
  <!-- Skill Evolution (v3.4.10 — Arsenal Evolution) -->
@@ -1786,25 +920,6 @@
1786
920
  </div>
1787
921
  </div>
1788
922
 
1789
- <!-- Math Health (V3) -->
1790
- <div class="tab-pane fade" id="math-health-pane">
1791
- <h5><i class="bi bi-calculator"></i> Mathematical Layer Health</h5>
1792
- <p class="text-muted">Status of Fisher-Rao, sheaf cohomology, and Langevin dynamics.</p>
1793
- <div class="row g-3" id="math-health-cards"></div>
1794
- </div>
1795
-
1796
- <!-- IDE Connections (V3) -->
1797
- <div class="tab-pane fade" id="ide-pane">
1798
- <h5><i class="bi bi-plug"></i> IDE Connections</h5>
1799
- <p class="text-muted">Manage IDE integrations. Connect new IDEs or check connection status.</p>
1800
- <button class="btn btn-primary mb-3" id="ide-connect-all-btn"><i class="bi bi-link-45deg"></i> Connect All Detected IDEs</button>
1801
- <div id="ide-list" class="table-responsive">
1802
- <table class="table table-sm">
1803
- <thead><tr><th>IDE</th><th>Installed</th><th>Config Path</th><th>Action</th></tr></thead>
1804
- <tbody id="ide-list-body"></tbody>
1805
- </table>
1806
- </div>
1807
- </div>
1808
923
 
1809
924
  <!-- Settings & Backup -->
1810
925
  <div class="tab-pane fade" id="settings-pane">
@@ -2095,17 +1210,17 @@
2095
1210
  </div>
2096
1211
  </div>
2097
1212
 
2098
- <!-- Bootstrap JS -->
2099
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
2100
- <!-- D3.js (kept for backward compatibility) -->
2101
- <script src="https://d3js.org/d3.v7.min.js"></script>
1213
+ <!-- Bootstrap JS (vendored locally v3.4.21 — offline-safe, no CDN leak) -->
1214
+ <script src="static/vendor/bootstrap.bundle.min.js"></script>
1215
+ <!-- D3.js (vendored) -->
1216
+ <script src="static/vendor/d3.v7.min.js"></script>
2102
1217
 
2103
1218
  <!-- Cytoscape.js REMOVED in v3.4.1 — replaced by Sigma.js WebGL -->
2104
1219
 
2105
- <!-- Sigma.js v3 + graphology (v3.4.1 — WebGL graph) -->
2106
- <script src="https://cdn.jsdelivr.net/npm/graphology@0.25.4/dist/graphology.umd.min.js"></script>
2107
- <script src="https://cdn.jsdelivr.net/npm/graphology-library@0.8.0/dist/graphology-library.min.js"></script>
2108
- <script src="https://cdn.jsdelivr.net/npm/sigma@2.4.0/build/sigma.min.js"></script>
1220
+ <!-- Sigma.js v3 + graphology (vendored) -->
1221
+ <script src="static/vendor/graphology.umd.min.js"></script>
1222
+ <script src="static/vendor/graphology-library.min.js"></script>
1223
+ <script src="static/vendor/sigma.min.js"></script>
2109
1224
 
2110
1225
  <!-- Modular JS (v2.5 — split from monolith app.js) -->
2111
1226
  <script src="static/js/core.js"></script>
@@ -2128,34 +1243,33 @@
2128
1243
  <script src="static/js/memories.js"></script>
2129
1244
  <script src="static/js/search.js"></script>
2130
1245
  <script src="static/js/modal.js"></script>
2131
- <script src="static/js/clusters.js"></script>
2132
- <script src="static/js/patterns.js"></script>
1246
+ <script src="static/js/clusters.js?v=34421"></script>
2133
1247
  <script src="static/js/timeline.js"></script>
2134
1248
  <script src="static/js/profiles.js"></script>
2135
1249
  <script src="static/js/settings.js"></script>
2136
1250
  <script src="static/js/events.js"></script>
2137
1251
  <script src="static/js/agents.js"></script>
2138
- <script src="static/js/learning.js"></script>
1252
+ <!-- Brain tab (v3.4.21 — XSS-safe DOM, token-gated, strict CSP on /api/v3/brain) -->
1253
+ <script src="static/js/brain.js?v=34421" defer></script>
2139
1254
  <script src="static/js/feedback.js"></script>
2140
1255
  <script src="static/js/lifecycle.js"></script>
2141
- <script src="static/js/behavioral.js"></script>
2142
1256
  <script src="static/js/compliance.js"></script>
2143
- <script src="static/js/init.js"></script>
1257
+ <script src="static/js/init.js?v=34421fix"></script>
2144
1258
  <script src="static/js/dashboard.js"></script>
2145
1259
  <script src="static/js/recall-lab.js"></script>
2146
- <script src="static/js/trust-dashboard.js"></script>
1260
+ <script src="static/js/trust-dashboard.js?v=34421"></script>
2147
1261
  <script src="static/js/math-health.js"></script>
2148
1262
  <script src="static/js/auto-settings.js"></script>
2149
1263
  <script src="static/js/ide-status.js"></script>
2150
1264
  <script src="static/js/fact-detail.js"></script>
2151
1265
 
2152
- <!-- Neural Glass v3.4.4 Dashboard V2 -->
1266
+ <!-- Neural Glass shell (v3.4.21 restructured) -->
2153
1267
  <script src="static/js/ng-health.js?v=345"></script>
2154
1268
  <script src="static/js/ng-ingestion.js?v=345"></script>
2155
1269
  <script src="static/js/ng-entities.js?v=3410"></script>
2156
1270
  <script src="static/js/ng-skills.js?v=3411"></script>
2157
1271
  <script src="static/js/ng-mesh.js?v=345"></script>
2158
- <script src="static/js/ng-shell.js?v=3410"></script>
1272
+ <script src="static/js/ng-shell.js?v=34421g"></script>
2159
1273
 
2160
1274
  <footer style="text-align:center; padding:24px; border-top:1px solid var(--bs-border-color); font-size:0.8125rem;">
2161
1275
  <div style="display:flex; align-items:center; justify-content:center; gap:8px; margin-bottom:8px;">