superlocalmemory 4.1.13 → 4.1.15

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 (740) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +103 -0
  3. package/README.md +3 -3
  4. package/package.json +1 -8
  5. package/plugin/.claude-plugin/plugin.json +1 -1
  6. package/plugin/CLAUDE.md +3 -3
  7. package/plugin/agents/slm-governance-advisor.md +1 -1
  8. package/plugin/agents/slm-loop-runner.md +1 -1
  9. package/plugin/agents/slm-memory-advisor.md +1 -1
  10. package/plugin/agents/slm-optimize-advisor.md +1 -1
  11. package/plugin/requirements.txt +1 -1
  12. package/plugin/skills/slm-cache/SKILL.md +1 -1
  13. package/plugin/skills/slm-compress/SKILL.md +1 -1
  14. package/plugin/skills/slm-governance/SKILL.md +1 -1
  15. package/plugin/skills/slm-graph/SKILL.md +1 -1
  16. package/plugin/skills/slm-loop/SKILL.md +1 -1
  17. package/plugin/skills/slm-mesh/SKILL.md +1 -1
  18. package/plugin/skills/slm-profile/SKILL.md +1 -1
  19. package/plugin/skills/slm-recall/SKILL.md +1 -1
  20. package/plugin/skills/slm-remember/SKILL.md +1 -1
  21. package/plugin/skills/slm-scope/SKILL.md +1 -1
  22. package/plugin/skills/slm-session/SKILL.md +1 -1
  23. package/plugin/skills/slm-status/SKILL.md +1 -1
  24. package/plugin-src/agents/slm-memory-advisor.md +1 -1
  25. package/plugin-src/agents/slm-optimize-advisor.md +1 -1
  26. package/plugin-src/rules/AGENTS.md +1 -1
  27. package/plugin-src/skills/slm-cache/SKILL.md +1 -1
  28. package/plugin-src/skills/slm-compress/SKILL.md +1 -1
  29. package/plugin-src/skills/slm-governance/SKILL.md +1 -1
  30. package/plugin-src/skills/slm-graph/SKILL.md +1 -1
  31. package/plugin-src/skills/slm-loop/SKILL.md +1 -1
  32. package/plugin-src/skills/slm-mesh/SKILL.md +1 -1
  33. package/plugin-src/skills/slm-profile/SKILL.md +1 -1
  34. package/plugin-src/skills/slm-recall/SKILL.md +1 -1
  35. package/plugin-src/skills/slm-remember/SKILL.md +1 -1
  36. package/plugin-src/skills/slm-scope/SKILL.md +1 -1
  37. package/plugin-src/skills/slm-session/SKILL.md +1 -1
  38. package/plugin-src/skills/slm-status/SKILL.md +1 -1
  39. package/scripts/postinstall.js +71 -2
  40. package/pyproject.toml +0 -250
  41. package/src/superlocalmemory/__init__.py +0 -82
  42. package/src/superlocalmemory/access/__init__.py +0 -3
  43. package/src/superlocalmemory/access/rbac.py +0 -575
  44. package/src/superlocalmemory/attribution/__init__.py +0 -9
  45. package/src/superlocalmemory/attribution/signer.py +0 -173
  46. package/src/superlocalmemory/attribution/watermark.py +0 -189
  47. package/src/superlocalmemory/brain/__init__.py +0 -5
  48. package/src/superlocalmemory/brain/truth.py +0 -418
  49. package/src/superlocalmemory/cli/__init__.py +0 -5
  50. package/src/superlocalmemory/cli/__main__.py +0 -17
  51. package/src/superlocalmemory/cli/_lazy_init.py +0 -115
  52. package/src/superlocalmemory/cli/cache_cmd.py +0 -198
  53. package/src/superlocalmemory/cli/commands.py +0 -4710
  54. package/src/superlocalmemory/cli/compress_cmd.py +0 -151
  55. package/src/superlocalmemory/cli/context_commands.py +0 -193
  56. package/src/superlocalmemory/cli/daemon.py +0 -909
  57. package/src/superlocalmemory/cli/db_migrate.py +0 -150
  58. package/src/superlocalmemory/cli/diagnostics_cmd.py +0 -101
  59. package/src/superlocalmemory/cli/escape_hatch.py +0 -220
  60. package/src/superlocalmemory/cli/evidence_cmd.py +0 -103
  61. package/src/superlocalmemory/cli/gdpr_cmd.py +0 -792
  62. package/src/superlocalmemory/cli/gdpr_io.py +0 -109
  63. package/src/superlocalmemory/cli/help_cmd.py +0 -197
  64. package/src/superlocalmemory/cli/host_upgrades.py +0 -189
  65. package/src/superlocalmemory/cli/ingest_cmd.py +0 -327
  66. package/src/superlocalmemory/cli/json_output.py +0 -81
  67. package/src/superlocalmemory/cli/loop_cmd.py +0 -187
  68. package/src/superlocalmemory/cli/main.py +0 -1145
  69. package/src/superlocalmemory/cli/mesh_cmd.py +0 -38
  70. package/src/superlocalmemory/cli/migrate_cmd.py +0 -55
  71. package/src/superlocalmemory/cli/ops_cmd.py +0 -281
  72. package/src/superlocalmemory/cli/optimize_cmd.py +0 -179
  73. package/src/superlocalmemory/cli/optimize_constants.py +0 -31
  74. package/src/superlocalmemory/cli/pending_store.py +0 -296
  75. package/src/superlocalmemory/cli/proxy_cmd.py +0 -108
  76. package/src/superlocalmemory/cli/scale_engine_cmd.py +0 -56
  77. package/src/superlocalmemory/cli/service_installer.py +0 -373
  78. package/src/superlocalmemory/cli/setup_wizard.py +0 -1162
  79. package/src/superlocalmemory/cli/summary_cmd.py +0 -215
  80. package/src/superlocalmemory/cli/version_banner.py +0 -202
  81. package/src/superlocalmemory/cli/wizard_v3426_options.py +0 -129
  82. package/src/superlocalmemory/code_graph/__init__.py +0 -46
  83. package/src/superlocalmemory/code_graph/blast_radius.py +0 -177
  84. package/src/superlocalmemory/code_graph/bridge/__init__.py +0 -36
  85. package/src/superlocalmemory/code_graph/bridge/entity_resolver.py +0 -490
  86. package/src/superlocalmemory/code_graph/bridge/event_listeners.py +0 -206
  87. package/src/superlocalmemory/code_graph/bridge/fact_enricher.py +0 -159
  88. package/src/superlocalmemory/code_graph/bridge/hebbian_linker.py +0 -170
  89. package/src/superlocalmemory/code_graph/bridge/maintenance.py +0 -220
  90. package/src/superlocalmemory/code_graph/bridge/temporal_checker.py +0 -152
  91. package/src/superlocalmemory/code_graph/changes.py +0 -363
  92. package/src/superlocalmemory/code_graph/communities.py +0 -299
  93. package/src/superlocalmemory/code_graph/config.py +0 -154
  94. package/src/superlocalmemory/code_graph/database.py +0 -526
  95. package/src/superlocalmemory/code_graph/extractors/__init__.py +0 -95
  96. package/src/superlocalmemory/code_graph/extractors/python.py +0 -413
  97. package/src/superlocalmemory/code_graph/extractors/typescript.py +0 -556
  98. package/src/superlocalmemory/code_graph/flows.py +0 -350
  99. package/src/superlocalmemory/code_graph/git_hooks.py +0 -226
  100. package/src/superlocalmemory/code_graph/graph_engine.py +0 -295
  101. package/src/superlocalmemory/code_graph/graph_store.py +0 -335
  102. package/src/superlocalmemory/code_graph/incremental.py +0 -200
  103. package/src/superlocalmemory/code_graph/models.py +0 -130
  104. package/src/superlocalmemory/code_graph/parser.py +0 -687
  105. package/src/superlocalmemory/code_graph/resolver.py +0 -321
  106. package/src/superlocalmemory/code_graph/search.py +0 -460
  107. package/src/superlocalmemory/code_graph/service.py +0 -95
  108. package/src/superlocalmemory/code_graph/watcher.py +0 -207
  109. package/src/superlocalmemory/compliance/__init__.py +0 -0
  110. package/src/superlocalmemory/compliance/abac.py +0 -204
  111. package/src/superlocalmemory/compliance/audit.py +0 -385
  112. package/src/superlocalmemory/compliance/eu_ai_act.py +0 -101
  113. package/src/superlocalmemory/compliance/gdpr.py +0 -1479
  114. package/src/superlocalmemory/compliance/lifecycle.py +0 -158
  115. package/src/superlocalmemory/compliance/retention.py +0 -415
  116. package/src/superlocalmemory/compliance/scheduler.py +0 -217
  117. package/src/superlocalmemory/contracts/__init__.py +0 -1
  118. package/src/superlocalmemory/contracts/schemas/agent-experience-v1.schema.json +0 -92
  119. package/src/superlocalmemory/contracts/schemas/agent-integration-contract-v2.schema.json +0 -46
  120. package/src/superlocalmemory/contracts/schemas/cognitive-turn-receipt-v1.schema.json +0 -59
  121. package/src/superlocalmemory/contracts/v402.py +0 -62
  122. package/src/superlocalmemory/core/__init__.py +0 -0
  123. package/src/superlocalmemory/core/actor_context.py +0 -166
  124. package/src/superlocalmemory/core/admission.py +0 -769
  125. package/src/superlocalmemory/core/backend_orchestrator.py +0 -637
  126. package/src/superlocalmemory/core/block_hygiene.py +0 -147
  127. package/src/superlocalmemory/core/community_summary.py +0 -267
  128. package/src/superlocalmemory/core/component_healer.py +0 -144
  129. package/src/superlocalmemory/core/component_registry.py +0 -514
  130. package/src/superlocalmemory/core/config.py +0 -2204
  131. package/src/superlocalmemory/core/consolidation_engine.py +0 -983
  132. package/src/superlocalmemory/core/context_cache.py +0 -574
  133. package/src/superlocalmemory/core/derivation_lineage.py +0 -246
  134. package/src/superlocalmemory/core/embedding_worker.py +0 -208
  135. package/src/superlocalmemory/core/embeddings.py +0 -1052
  136. package/src/superlocalmemory/core/engine.py +0 -1395
  137. package/src/superlocalmemory/core/engine_capabilities.py +0 -24
  138. package/src/superlocalmemory/core/engine_ingestion.py +0 -983
  139. package/src/superlocalmemory/core/engine_lock.py +0 -75
  140. package/src/superlocalmemory/core/engine_wiring.py +0 -776
  141. package/src/superlocalmemory/core/entity_community.py +0 -178
  142. package/src/superlocalmemory/core/error_envelope.py +0 -60
  143. package/src/superlocalmemory/core/evidence_bundle.py +0 -528
  144. package/src/superlocalmemory/core/fact_consolidator.py +0 -812
  145. package/src/superlocalmemory/core/file_lock.py +0 -92
  146. package/src/superlocalmemory/core/graph_analyzer.py +0 -456
  147. package/src/superlocalmemory/core/graph_metrics.py +0 -597
  148. package/src/superlocalmemory/core/graph_pruner.py +0 -939
  149. package/src/superlocalmemory/core/health_monitor.py +0 -338
  150. package/src/superlocalmemory/core/hooks.py +0 -65
  151. package/src/superlocalmemory/core/ingest_gate.py +0 -133
  152. package/src/superlocalmemory/core/ingest_policy.py +0 -38
  153. package/src/superlocalmemory/core/ingestion_command.py +0 -1042
  154. package/src/superlocalmemory/core/injection.py +0 -434
  155. package/src/superlocalmemory/core/install_detector.py +0 -131
  156. package/src/superlocalmemory/core/key_expander.py +0 -138
  157. package/src/superlocalmemory/core/lifecycle_state.py +0 -153
  158. package/src/superlocalmemory/core/maintenance.py +0 -777
  159. package/src/superlocalmemory/core/maintenance_scheduler.py +0 -507
  160. package/src/superlocalmemory/core/materialization_control.py +0 -20
  161. package/src/superlocalmemory/core/mcp_embedder_proxy.py +0 -89
  162. package/src/superlocalmemory/core/memory_health.py +0 -266
  163. package/src/superlocalmemory/core/mode_capability.py +0 -111
  164. package/src/superlocalmemory/core/modes.py +0 -168
  165. package/src/superlocalmemory/core/mutations.py +0 -688
  166. package/src/superlocalmemory/core/ollama_embedder.py +0 -266
  167. package/src/superlocalmemory/core/ollama_validator.py +0 -315
  168. package/src/superlocalmemory/core/operation_policy.py +0 -92
  169. package/src/superlocalmemory/core/operation_policy_registry.py +0 -542
  170. package/src/superlocalmemory/core/operation_request.py +0 -127
  171. package/src/superlocalmemory/core/ops_remediation.py +0 -542
  172. package/src/superlocalmemory/core/pii.py +0 -105
  173. package/src/superlocalmemory/core/platform_utils.py +0 -138
  174. package/src/superlocalmemory/core/profiles.py +0 -234
  175. package/src/superlocalmemory/core/progressive_abstraction.py +0 -208
  176. package/src/superlocalmemory/core/projection_drain.py +0 -380
  177. package/src/superlocalmemory/core/queue_consumer.py +0 -168
  178. package/src/superlocalmemory/core/ram_lock.py +0 -160
  179. package/src/superlocalmemory/core/rate_limit.py +0 -151
  180. package/src/superlocalmemory/core/recall_gate.py +0 -95
  181. package/src/superlocalmemory/core/recall_pipeline.py +0 -1337
  182. package/src/superlocalmemory/core/recall_queue.py +0 -377
  183. package/src/superlocalmemory/core/recall_worker.py +0 -414
  184. package/src/superlocalmemory/core/registry.py +0 -121
  185. package/src/superlocalmemory/core/remember_admission.py +0 -161
  186. package/src/superlocalmemory/core/remember_runtime.py +0 -1190
  187. package/src/superlocalmemory/core/remote_mode.py +0 -214
  188. package/src/superlocalmemory/core/reranker_worker.py +0 -338
  189. package/src/superlocalmemory/core/safe_fs.py +0 -108
  190. package/src/superlocalmemory/core/scale_autopromote.py +0 -196
  191. package/src/superlocalmemory/core/scale_engine.py +0 -915
  192. package/src/superlocalmemory/core/score_contract.py +0 -82
  193. package/src/superlocalmemory/core/security_primitives.py +0 -672
  194. package/src/superlocalmemory/core/session_identity.py +0 -98
  195. package/src/superlocalmemory/core/shadow_router.py +0 -319
  196. package/src/superlocalmemory/core/slm_disabled.py +0 -85
  197. package/src/superlocalmemory/core/status_contract.py +0 -108
  198. package/src/superlocalmemory/core/store_pipeline.py +0 -1404
  199. package/src/superlocalmemory/core/summarizer.py +0 -200
  200. package/src/superlocalmemory/core/tier_manager.py +0 -461
  201. package/src/superlocalmemory/core/topic_signature.py +0 -156
  202. package/src/superlocalmemory/core/transactions/__init__.py +0 -78
  203. package/src/superlocalmemory/core/transactions/concrete_owners.py +0 -604
  204. package/src/superlocalmemory/core/transactions/erasure.py +0 -825
  205. package/src/superlocalmemory/core/transactions/manifest.py +0 -255
  206. package/src/superlocalmemory/core/transactions/manifest_key.py +0 -155
  207. package/src/superlocalmemory/core/transactions/obligations.py +0 -272
  208. package/src/superlocalmemory/core/transactions/owners.py +0 -114
  209. package/src/superlocalmemory/core/transactions/reconciler.py +0 -285
  210. package/src/superlocalmemory/core/transactions/service.py +0 -330
  211. package/src/superlocalmemory/core/worker_pool.py +0 -377
  212. package/src/superlocalmemory/core/working_memory.py +0 -288
  213. package/src/superlocalmemory/dynamics/__init__.py +0 -0
  214. package/src/superlocalmemory/dynamics/activation_guided_quantization.py +0 -374
  215. package/src/superlocalmemory/dynamics/eap_scheduler.py +0 -294
  216. package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +0 -171
  217. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +0 -227
  218. package/src/superlocalmemory/encoding/__init__.py +0 -0
  219. package/src/superlocalmemory/encoding/auto_linker.py +0 -308
  220. package/src/superlocalmemory/encoding/cognitive_consolidator.py +0 -899
  221. package/src/superlocalmemory/encoding/consolidator.py +0 -472
  222. package/src/superlocalmemory/encoding/context_generator.py +0 -175
  223. package/src/superlocalmemory/encoding/emotional.py +0 -189
  224. package/src/superlocalmemory/encoding/entity_reflexion.py +0 -200
  225. package/src/superlocalmemory/encoding/entity_resolver.py +0 -687
  226. package/src/superlocalmemory/encoding/entropy_gate.py +0 -101
  227. package/src/superlocalmemory/encoding/fact_extractor.py +0 -877
  228. package/src/superlocalmemory/encoding/foresight.py +0 -93
  229. package/src/superlocalmemory/encoding/graph_builder.py +0 -346
  230. package/src/superlocalmemory/encoding/observation_builder.py +0 -177
  231. package/src/superlocalmemory/encoding/prospective_markers.py +0 -262
  232. package/src/superlocalmemory/encoding/scene_builder.py +0 -410
  233. package/src/superlocalmemory/encoding/signal_inference.py +0 -90
  234. package/src/superlocalmemory/encoding/temporal_parser.py +0 -432
  235. package/src/superlocalmemory/encoding/temporal_validator.py +0 -572
  236. package/src/superlocalmemory/encoding/type_router.py +0 -237
  237. package/src/superlocalmemory/evaluation/__init__.py +0 -13
  238. package/src/superlocalmemory/evaluation/calibration.py +0 -308
  239. package/src/superlocalmemory/evolution/__init__.py +0 -29
  240. package/src/superlocalmemory/evolution/blind_verifier.py +0 -122
  241. package/src/superlocalmemory/evolution/budget.py +0 -356
  242. package/src/superlocalmemory/evolution/evolution_store.py +0 -619
  243. package/src/superlocalmemory/evolution/llm_dispatch.py +0 -559
  244. package/src/superlocalmemory/evolution/model_selection.py +0 -175
  245. package/src/superlocalmemory/evolution/mutation_generator.py +0 -226
  246. package/src/superlocalmemory/evolution/skill_activator.py +0 -270
  247. package/src/superlocalmemory/evolution/skill_evolver.py +0 -928
  248. package/src/superlocalmemory/evolution/triggers.py +0 -376
  249. package/src/superlocalmemory/evolution/types.py +0 -114
  250. package/src/superlocalmemory/graph/__init__.py +0 -9
  251. package/src/superlocalmemory/graph/cozo_adjacency.py +0 -122
  252. package/src/superlocalmemory/graph/cozo_backend.py +0 -751
  253. package/src/superlocalmemory/hooks/__init__.py +0 -3
  254. package/src/superlocalmemory/hooks/_outcome_common.py +0 -523
  255. package/src/superlocalmemory/hooks/adapter_base.py +0 -347
  256. package/src/superlocalmemory/hooks/antigravity_adapter.py +0 -171
  257. package/src/superlocalmemory/hooks/auto_capture.py +0 -133
  258. package/src/superlocalmemory/hooks/auto_invoker.py +0 -521
  259. package/src/superlocalmemory/hooks/auto_parameterize.py +0 -147
  260. package/src/superlocalmemory/hooks/auto_recall.py +0 -191
  261. package/src/superlocalmemory/hooks/auto_recall_hook.py +0 -251
  262. package/src/superlocalmemory/hooks/before_web_hook.py +0 -131
  263. package/src/superlocalmemory/hooks/claude_code_hooks.py +0 -637
  264. package/src/superlocalmemory/hooks/codex_assets.py +0 -251
  265. package/src/superlocalmemory/hooks/codex_hooks.py +0 -186
  266. package/src/superlocalmemory/hooks/context_payload.py +0 -311
  267. package/src/superlocalmemory/hooks/copilot_adapter.py +0 -208
  268. package/src/superlocalmemory/hooks/cross_platform_connector.py +0 -90
  269. package/src/superlocalmemory/hooks/cursor_adapter.py +0 -173
  270. package/src/superlocalmemory/hooks/hook_daemon.py +0 -295
  271. package/src/superlocalmemory/hooks/hook_handlers.py +0 -822
  272. package/src/superlocalmemory/hooks/ide_connector.py +0 -246
  273. package/src/superlocalmemory/hooks/memory_protocol.py +0 -158
  274. package/src/superlocalmemory/hooks/portable_kit.py +0 -755
  275. package/src/superlocalmemory/hooks/post_tool_async_hook.py +0 -183
  276. package/src/superlocalmemory/hooks/post_tool_outcome_hook.py +0 -351
  277. package/src/superlocalmemory/hooks/prewarm_auth.py +0 -187
  278. package/src/superlocalmemory/hooks/rules_engine.py +0 -99
  279. package/src/superlocalmemory/hooks/session_registry.py +0 -330
  280. package/src/superlocalmemory/hooks/stop_outcome_hook.py +0 -138
  281. package/src/superlocalmemory/hooks/sync_loop.py +0 -114
  282. package/src/superlocalmemory/hooks/topic_shift_hook.py +0 -302
  283. package/src/superlocalmemory/hooks/user_prompt_hook.py +0 -131
  284. package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +0 -210
  285. package/src/superlocalmemory/infra/__init__.py +0 -3
  286. package/src/superlocalmemory/infra/auth_middleware.py +0 -145
  287. package/src/superlocalmemory/infra/backup.py +0 -974
  288. package/src/superlocalmemory/infra/backup_obligations.py +0 -423
  289. package/src/superlocalmemory/infra/cache_manager.py +0 -267
  290. package/src/superlocalmemory/infra/cloud_backup.py +0 -788
  291. package/src/superlocalmemory/infra/daemon_identity.py +0 -300
  292. package/src/superlocalmemory/infra/data_root.py +0 -238
  293. package/src/superlocalmemory/infra/event_bus.py +0 -637
  294. package/src/superlocalmemory/infra/local_diagnostics.py +0 -327
  295. package/src/superlocalmemory/infra/pid_manager.py +0 -193
  296. package/src/superlocalmemory/infra/process_identity.py +0 -180
  297. package/src/superlocalmemory/infra/process_reaper.py +0 -624
  298. package/src/superlocalmemory/infra/rate_limiter.py +0 -228
  299. package/src/superlocalmemory/infra/self_heal.py +0 -401
  300. package/src/superlocalmemory/infra/version_integrity.py +0 -229
  301. package/src/superlocalmemory/ingestion/__init__.py +0 -13
  302. package/src/superlocalmemory/ingestion/adapter_manager.py +0 -255
  303. package/src/superlocalmemory/ingestion/base_adapter.py +0 -171
  304. package/src/superlocalmemory/ingestion/calendar_adapter.py +0 -349
  305. package/src/superlocalmemory/ingestion/credentials.py +0 -125
  306. package/src/superlocalmemory/ingestion/gmail_adapter.py +0 -378
  307. package/src/superlocalmemory/ingestion/parsers.py +0 -100
  308. package/src/superlocalmemory/ingestion/transcript_adapter.py +0 -161
  309. package/src/superlocalmemory/integrations/__init__.py +0 -1
  310. package/src/superlocalmemory/integrations/bounded_loops_mcp.py +0 -431
  311. package/src/superlocalmemory/integrations/bounded_loops_v051.py +0 -236
  312. package/src/superlocalmemory/learning/__init__.py +0 -0
  313. package/src/superlocalmemory/learning/adaptive.py +0 -172
  314. package/src/superlocalmemory/learning/arm_catalog.py +0 -97
  315. package/src/superlocalmemory/learning/assertion_miner.py +0 -403
  316. package/src/superlocalmemory/learning/bandit.py +0 -654
  317. package/src/superlocalmemory/learning/bandit_cache.py +0 -131
  318. package/src/superlocalmemory/learning/behavioral.py +0 -542
  319. package/src/superlocalmemory/learning/bootstrap.py +0 -298
  320. package/src/superlocalmemory/learning/consolidation_cycle.py +0 -398
  321. package/src/superlocalmemory/learning/consolidation_quantization_worker.py +0 -115
  322. package/src/superlocalmemory/learning/consolidation_worker.py +0 -261
  323. package/src/superlocalmemory/learning/cross_project.py +0 -408
  324. package/src/superlocalmemory/learning/database.py +0 -698
  325. package/src/superlocalmemory/learning/dedup_hnsw.py +0 -413
  326. package/src/superlocalmemory/learning/engagement.py +0 -487
  327. package/src/superlocalmemory/learning/engagement_features.py +0 -279
  328. package/src/superlocalmemory/learning/ensemble.py +0 -309
  329. package/src/superlocalmemory/learning/entity_compiler.py +0 -356
  330. package/src/superlocalmemory/learning/fact_outcome_joins.py +0 -207
  331. package/src/superlocalmemory/learning/features.py +0 -138
  332. package/src/superlocalmemory/learning/feedback.py +0 -724
  333. package/src/superlocalmemory/learning/forgetting_scheduler.py +0 -375
  334. package/src/superlocalmemory/learning/hnsw_dedup.py +0 -69
  335. package/src/superlocalmemory/learning/labeler.py +0 -85
  336. package/src/superlocalmemory/learning/legacy_migration.py +0 -316
  337. package/src/superlocalmemory/learning/lightgbm_subprocess.py +0 -236
  338. package/src/superlocalmemory/learning/memory_merge.py +0 -175
  339. package/src/superlocalmemory/learning/model_cache.py +0 -267
  340. package/src/superlocalmemory/learning/model_rollback.py +0 -281
  341. package/src/superlocalmemory/learning/outcome_queue.py +0 -306
  342. package/src/superlocalmemory/learning/outcomes.py +0 -286
  343. package/src/superlocalmemory/learning/pattern_miner.py +0 -465
  344. package/src/superlocalmemory/learning/pattern_miner_constants.py +0 -90
  345. package/src/superlocalmemory/learning/pcos.py +0 -291
  346. package/src/superlocalmemory/learning/project_context.py +0 -366
  347. package/src/superlocalmemory/learning/propensity.py +0 -131
  348. package/src/superlocalmemory/learning/ranker.py +0 -300
  349. package/src/superlocalmemory/learning/ranker_common.py +0 -163
  350. package/src/superlocalmemory/learning/ranker_retrain_legacy.py +0 -210
  351. package/src/superlocalmemory/learning/ranker_retrain_online.py +0 -423
  352. package/src/superlocalmemory/learning/reward.py +0 -888
  353. package/src/superlocalmemory/learning/reward_archive.py +0 -223
  354. package/src/superlocalmemory/learning/reward_boost.py +0 -211
  355. package/src/superlocalmemory/learning/reward_from_outcomes.py +0 -365
  356. package/src/superlocalmemory/learning/reward_model.py +0 -144
  357. package/src/superlocalmemory/learning/reward_proxy.py +0 -578
  358. package/src/superlocalmemory/learning/shadow_test.py +0 -524
  359. package/src/superlocalmemory/learning/signal_kinds.py +0 -79
  360. package/src/superlocalmemory/learning/signal_worker.py +0 -268
  361. package/src/superlocalmemory/learning/signals.py +0 -646
  362. package/src/superlocalmemory/learning/skill_performance_miner.py +0 -422
  363. package/src/superlocalmemory/learning/source_quality.py +0 -828
  364. package/src/superlocalmemory/learning/trigram_index.py +0 -548
  365. package/src/superlocalmemory/learning/workflows.py +0 -309
  366. package/src/superlocalmemory/llm/__init__.py +0 -0
  367. package/src/superlocalmemory/llm/backbone.py +0 -364
  368. package/src/superlocalmemory/loops/__init__.py +0 -58
  369. package/src/superlocalmemory/loops/budget.py +0 -58
  370. package/src/superlocalmemory/loops/engine.py +0 -174
  371. package/src/superlocalmemory/loops/ledger.py +0 -298
  372. package/src/superlocalmemory/loops/models.py +0 -152
  373. package/src/superlocalmemory/loops/rules.py +0 -52
  374. package/src/superlocalmemory/math/__init__.py +0 -0
  375. package/src/superlocalmemory/math/ebbinghaus.py +0 -352
  376. package/src/superlocalmemory/math/fisher.py +0 -356
  377. package/src/superlocalmemory/math/fisher_quantized.py +0 -255
  378. package/src/superlocalmemory/math/hopfield.py +0 -282
  379. package/src/superlocalmemory/math/langevin.py +0 -411
  380. package/src/superlocalmemory/math/polar_quant.py +0 -414
  381. package/src/superlocalmemory/math/qjl.py +0 -115
  382. package/src/superlocalmemory/math/sheaf.py +0 -261
  383. package/src/superlocalmemory/math/turbo_quant.py +0 -318
  384. package/src/superlocalmemory/mcp/__init__.py +0 -0
  385. package/src/superlocalmemory/mcp/_daemon_proxy.py +0 -203
  386. package/src/superlocalmemory/mcp/_pool_adapter.py +0 -181
  387. package/src/superlocalmemory/mcp/_stdin_guard.py +0 -60
  388. package/src/superlocalmemory/mcp/agent_context.py +0 -115
  389. package/src/superlocalmemory/mcp/cli_fallback.py +0 -602
  390. package/src/superlocalmemory/mcp/http_transport.py +0 -85
  391. package/src/superlocalmemory/mcp/profiles.py +0 -154
  392. package/src/superlocalmemory/mcp/resources.py +0 -281
  393. package/src/superlocalmemory/mcp/server.py +0 -480
  394. package/src/superlocalmemory/mcp/session_binding.py +0 -98
  395. package/src/superlocalmemory/mcp/shared.py +0 -112
  396. package/src/superlocalmemory/mcp/tools.py +0 -18
  397. package/src/superlocalmemory/mcp/tools_active.py +0 -958
  398. package/src/superlocalmemory/mcp/tools_brain.py +0 -298
  399. package/src/superlocalmemory/mcp/tools_code_graph.py +0 -1717
  400. package/src/superlocalmemory/mcp/tools_context.py +0 -239
  401. package/src/superlocalmemory/mcp/tools_core.py +0 -1112
  402. package/src/superlocalmemory/mcp/tools_evolution.py +0 -343
  403. package/src/superlocalmemory/mcp/tools_learning.py +0 -393
  404. package/src/superlocalmemory/mcp/tools_loops.py +0 -345
  405. package/src/superlocalmemory/mcp/tools_mesh.py +0 -429
  406. package/src/superlocalmemory/mcp/tools_ops.py +0 -115
  407. package/src/superlocalmemory/mcp/tools_optimize.py +0 -322
  408. package/src/superlocalmemory/mcp/tools_summaries.py +0 -147
  409. package/src/superlocalmemory/mcp/tools_v28.py +0 -292
  410. package/src/superlocalmemory/mcp/tools_v3.py +0 -398
  411. package/src/superlocalmemory/mcp/tools_v33.py +0 -507
  412. package/src/superlocalmemory/mesh/__init__.py +0 -12
  413. package/src/superlocalmemory/mesh/broker.py +0 -812
  414. package/src/superlocalmemory/mesh/broker_security.py +0 -470
  415. package/src/superlocalmemory/mesh/discovery.py +0 -365
  416. package/src/superlocalmemory/mesh/lock_protocol.py +0 -313
  417. package/src/superlocalmemory/mesh/node_identity.py +0 -97
  418. package/src/superlocalmemory/mesh/outbox_remote.py +0 -429
  419. package/src/superlocalmemory/mesh/remote_sync.py +0 -829
  420. package/src/superlocalmemory/mesh/state_sync.py +0 -286
  421. package/src/superlocalmemory/migrations/__init__.py +0 -5
  422. package/src/superlocalmemory/migrations/v3_4_25_to_v3_4_26.py +0 -144
  423. package/src/superlocalmemory/optimize/NOTICE +0 -6
  424. package/src/superlocalmemory/optimize/__init__.py +0 -0
  425. package/src/superlocalmemory/optimize/adapters/__init__.py +0 -68
  426. package/src/superlocalmemory/optimize/adapters/_agent_registry.py +0 -120
  427. package/src/superlocalmemory/optimize/adapters/anthropic_adapter.py +0 -112
  428. package/src/superlocalmemory/optimize/adapters/openai_adapter.py +0 -122
  429. package/src/superlocalmemory/optimize/adapters/wrap.py +0 -228
  430. package/src/superlocalmemory/optimize/cache/__init__.py +0 -31
  431. package/src/superlocalmemory/optimize/cache/boundary_store.py +0 -488
  432. package/src/superlocalmemory/optimize/cache/centroid_store.py +0 -199
  433. package/src/superlocalmemory/optimize/cache/context_key.py +0 -67
  434. package/src/superlocalmemory/optimize/cache/exact.py +0 -88
  435. package/src/superlocalmemory/optimize/cache/invalidation.py +0 -36
  436. package/src/superlocalmemory/optimize/cache/key_builder.py +0 -111
  437. package/src/superlocalmemory/optimize/cache/manager.py +0 -737
  438. package/src/superlocalmemory/optimize/cache/semantic.py +0 -637
  439. package/src/superlocalmemory/optimize/cache/stampede.py +0 -50
  440. package/src/superlocalmemory/optimize/compress/__init__.py +0 -17
  441. package/src/superlocalmemory/optimize/compress/align.py +0 -159
  442. package/src/superlocalmemory/optimize/compress/ccr.py +0 -116
  443. package/src/superlocalmemory/optimize/compress/prose_llmlingua.py +0 -71
  444. package/src/superlocalmemory/optimize/compress/router.py +0 -667
  445. package/src/superlocalmemory/optimize/config/__init__.py +0 -56
  446. package/src/superlocalmemory/optimize/config/defaults.py +0 -43
  447. package/src/superlocalmemory/optimize/config/schema.py +0 -327
  448. package/src/superlocalmemory/optimize/config/store.py +0 -270
  449. package/src/superlocalmemory/optimize/metrics/__init__.py +0 -8
  450. package/src/superlocalmemory/optimize/metrics/counters.py +0 -155
  451. package/src/superlocalmemory/optimize/metrics/estimator.py +0 -87
  452. package/src/superlocalmemory/optimize/metrics/exporters.py +0 -77
  453. package/src/superlocalmemory/optimize/metrics/persistence.py +0 -115
  454. package/src/superlocalmemory/optimize/proxy/__init__.py +0 -28
  455. package/src/superlocalmemory/optimize/proxy/_helpers.py +0 -730
  456. package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +0 -375
  457. package/src/superlocalmemory/optimize/proxy/capture.py +0 -550
  458. package/src/superlocalmemory/optimize/proxy/gemini_surface.py +0 -528
  459. package/src/superlocalmemory/optimize/proxy/lifecycle.py +0 -126
  460. package/src/superlocalmemory/optimize/proxy/openai_surface.py +0 -465
  461. package/src/superlocalmemory/optimize/proxy/server.py +0 -199
  462. package/src/superlocalmemory/optimize/proxy/vertex_surface.py +0 -246
  463. package/src/superlocalmemory/optimize/storage/__init__.py +0 -0
  464. package/src/superlocalmemory/optimize/storage/db.py +0 -1185
  465. package/src/superlocalmemory/optimize/storage/schema.py +0 -205
  466. package/src/superlocalmemory/parameterization/__init__.py +0 -47
  467. package/src/superlocalmemory/parameterization/cross_project.py +0 -12
  468. package/src/superlocalmemory/parameterization/pattern_extractor.py +0 -584
  469. package/src/superlocalmemory/parameterization/pii_filter.py +0 -106
  470. package/src/superlocalmemory/parameterization/prompt_injector.py +0 -219
  471. package/src/superlocalmemory/parameterization/prompt_lifecycle.py +0 -281
  472. package/src/superlocalmemory/parameterization/soft_prompt_generator.py +0 -542
  473. package/src/superlocalmemory/parameterization/workflow_miner.py +0 -17
  474. package/src/superlocalmemory/reliability/__init__.py +0 -45
  475. package/src/superlocalmemory/reliability/join_liveness.py +0 -301
  476. package/src/superlocalmemory/reliability/prior_distance.py +0 -243
  477. package/src/superlocalmemory/retrieval/__init__.py +0 -0
  478. package/src/superlocalmemory/retrieval/agentic.py +0 -367
  479. package/src/superlocalmemory/retrieval/ann_index.py +0 -235
  480. package/src/superlocalmemory/retrieval/bm25_channel.py +0 -451
  481. package/src/superlocalmemory/retrieval/bridge_discovery.py +0 -253
  482. package/src/superlocalmemory/retrieval/channel_registry.py +0 -154
  483. package/src/superlocalmemory/retrieval/channel_status.py +0 -117
  484. package/src/superlocalmemory/retrieval/engine.py +0 -1615
  485. package/src/superlocalmemory/retrieval/entity_channel.py +0 -994
  486. package/src/superlocalmemory/retrieval/forgetting_filter.py +0 -160
  487. package/src/superlocalmemory/retrieval/fusion.py +0 -81
  488. package/src/superlocalmemory/retrieval/graph_adjacency.py +0 -219
  489. package/src/superlocalmemory/retrieval/hopfield_channel.py +0 -465
  490. package/src/superlocalmemory/retrieval/profile_channel.py +0 -105
  491. package/src/superlocalmemory/retrieval/quantization_aware_search.py +0 -147
  492. package/src/superlocalmemory/retrieval/remote_reranker.py +0 -758
  493. package/src/superlocalmemory/retrieval/reranker.py +0 -674
  494. package/src/superlocalmemory/retrieval/scope_policy.py +0 -126
  495. package/src/superlocalmemory/retrieval/semantic_channel.py +0 -638
  496. package/src/superlocalmemory/retrieval/spreading.py +0 -288
  497. package/src/superlocalmemory/retrieval/spreading_activation.py +0 -616
  498. package/src/superlocalmemory/retrieval/strategy.py +0 -248
  499. package/src/superlocalmemory/retrieval/temporal_channel.py +0 -433
  500. package/src/superlocalmemory/retrieval/temporal_frame.py +0 -102
  501. package/src/superlocalmemory/retrieval/temporal_utils.py +0 -122
  502. package/src/superlocalmemory/retrieval/temporal_validity_filter.py +0 -499
  503. package/src/superlocalmemory/retrieval/time_window.py +0 -181
  504. package/src/superlocalmemory/retrieval/vector_store.py +0 -863
  505. package/src/superlocalmemory/server/__init__.py +0 -1
  506. package/src/superlocalmemory/server/api.py +0 -310
  507. package/src/superlocalmemory/server/asset_versions.py +0 -171
  508. package/src/superlocalmemory/server/bandit_loops.py +0 -158
  509. package/src/superlocalmemory/server/config_file.py +0 -90
  510. package/src/superlocalmemory/server/consolidation_runner.py +0 -140
  511. package/src/superlocalmemory/server/egress_policy.py +0 -258
  512. package/src/superlocalmemory/server/loopback.py +0 -85
  513. package/src/superlocalmemory/server/middleware/__init__.py +0 -11
  514. package/src/superlocalmemory/server/middleware/security_headers.py +0 -144
  515. package/src/superlocalmemory/server/origin.py +0 -55
  516. package/src/superlocalmemory/server/profile_runtime.py +0 -515
  517. package/src/superlocalmemory/server/rbac_enforce.py +0 -194
  518. package/src/superlocalmemory/server/recall_health.py +0 -343
  519. package/src/superlocalmemory/server/recall_serializer.py +0 -320
  520. package/src/superlocalmemory/server/route_mutations.py +0 -104
  521. package/src/superlocalmemory/server/routes/__init__.py +0 -4
  522. package/src/superlocalmemory/server/routes/abstraction.py +0 -314
  523. package/src/superlocalmemory/server/routes/adapters.py +0 -63
  524. package/src/superlocalmemory/server/routes/agents.py +0 -303
  525. package/src/superlocalmemory/server/routes/backup.py +0 -869
  526. package/src/superlocalmemory/server/routes/behavioral.py +0 -659
  527. package/src/superlocalmemory/server/routes/brain.py +0 -1892
  528. package/src/superlocalmemory/server/routes/chat.py +0 -393
  529. package/src/superlocalmemory/server/routes/compliance.py +0 -533
  530. package/src/superlocalmemory/server/routes/config_api.py +0 -703
  531. package/src/superlocalmemory/server/routes/data_io.py +0 -329
  532. package/src/superlocalmemory/server/routes/entity.py +0 -237
  533. package/src/superlocalmemory/server/routes/events.py +0 -214
  534. package/src/superlocalmemory/server/routes/evolution.py +0 -510
  535. package/src/superlocalmemory/server/routes/helpers.py +0 -499
  536. package/src/superlocalmemory/server/routes/ingest.py +0 -137
  537. package/src/superlocalmemory/server/routes/insights.py +0 -366
  538. package/src/superlocalmemory/server/routes/learning.py +0 -834
  539. package/src/superlocalmemory/server/routes/learning_telemetry.py +0 -154
  540. package/src/superlocalmemory/server/routes/lifecycle.py +0 -184
  541. package/src/superlocalmemory/server/routes/memories.py +0 -1661
  542. package/src/superlocalmemory/server/routes/mesh.py +0 -517
  543. package/src/superlocalmemory/server/routes/mesh_lock.py +0 -54
  544. package/src/superlocalmemory/server/routes/mesh_state.py +0 -63
  545. package/src/superlocalmemory/server/routes/optimize.py +0 -197
  546. package/src/superlocalmemory/server/routes/prewarm.py +0 -173
  547. package/src/superlocalmemory/server/routes/profiles.py +0 -292
  548. package/src/superlocalmemory/server/routes/ratelimit.py +0 -132
  549. package/src/superlocalmemory/server/routes/rbac.py +0 -366
  550. package/src/superlocalmemory/server/routes/stats.py +0 -385
  551. package/src/superlocalmemory/server/routes/tiers.py +0 -222
  552. package/src/superlocalmemory/server/routes/timeline.py +0 -258
  553. package/src/superlocalmemory/server/routes/token.py +0 -90
  554. package/src/superlocalmemory/server/routes/v3_api.py +0 -3023
  555. package/src/superlocalmemory/server/routes/ws.py +0 -171
  556. package/src/superlocalmemory/server/security_middleware.py +0 -89
  557. package/src/superlocalmemory/server/ui.py +0 -354
  558. package/src/superlocalmemory/server/unified_daemon.py +0 -6326
  559. package/src/superlocalmemory/server/write_identity.py +0 -195
  560. package/src/superlocalmemory/storage/__init__.py +0 -0
  561. package/src/superlocalmemory/storage/_migration_internals.py +0 -638
  562. package/src/superlocalmemory/storage/_schema_version.py +0 -174
  563. package/src/superlocalmemory/storage/access_log.py +0 -170
  564. package/src/superlocalmemory/storage/admission_codec.py +0 -129
  565. package/src/superlocalmemory/storage/admission_journal.py +0 -843
  566. package/src/superlocalmemory/storage/agent_experience.py +0 -546
  567. package/src/superlocalmemory/storage/backup.py +0 -531
  568. package/src/superlocalmemory/storage/correction_cases.py +0 -670
  569. package/src/superlocalmemory/storage/database.py +0 -3180
  570. package/src/superlocalmemory/storage/deferred_writes.py +0 -209
  571. package/src/superlocalmemory/storage/embedding_codec.py +0 -200
  572. package/src/superlocalmemory/storage/embedding_migrator.py +0 -672
  573. package/src/superlocalmemory/storage/erasure_fence.py +0 -45
  574. package/src/superlocalmemory/storage/execution_learning.py +0 -285
  575. package/src/superlocalmemory/storage/external_evidence.py +0 -359
  576. package/src/superlocalmemory/storage/generation_fence.py +0 -63
  577. package/src/superlocalmemory/storage/lineage_retention.py +0 -236
  578. package/src/superlocalmemory/storage/logical_edges.py +0 -86
  579. package/src/superlocalmemory/storage/memory_write.py +0 -115
  580. package/src/superlocalmemory/storage/migration_runner.py +0 -895
  581. package/src/superlocalmemory/storage/migration_v33.py +0 -140
  582. package/src/superlocalmemory/storage/migrations/M001_add_signal_features_columns.py +0 -67
  583. package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +0 -107
  584. package/src/superlocalmemory/storage/migrations/M003_migration_log.py +0 -38
  585. package/src/superlocalmemory/storage/migrations/M004_cross_platform_sync_log.py +0 -46
  586. package/src/superlocalmemory/storage/migrations/M005_bandit_tables.py +0 -75
  587. package/src/superlocalmemory/storage/migrations/M006_action_outcomes_reward.py +0 -75
  588. package/src/superlocalmemory/storage/migrations/M007_pending_outcomes.py +0 -63
  589. package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +0 -94
  590. package/src/superlocalmemory/storage/migrations/M010_evolution_config.py +0 -80
  591. package/src/superlocalmemory/storage/migrations/M011_archive_and_merge.py +0 -87
  592. package/src/superlocalmemory/storage/migrations/M012_shadow_observations.py +0 -72
  593. package/src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py +0 -55
  594. package/src/superlocalmemory/storage/migrations/M014_v345_scale_ready.py +0 -45
  595. package/src/superlocalmemory/storage/migrations/M015_add_pinned_column.py +0 -58
  596. package/src/superlocalmemory/storage/migrations/M016_add_scope_support.py +0 -120
  597. package/src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py +0 -79
  598. package/src/superlocalmemory/storage/migrations/M018_ingestion_operations.py +0 -120
  599. package/src/superlocalmemory/storage/migrations/M019_derivation_lineage.py +0 -54
  600. package/src/superlocalmemory/storage/migrations/M020_model_state_integrity.py +0 -52
  601. package/src/superlocalmemory/storage/migrations/M021_ingestion_log_profile.py +0 -108
  602. package/src/superlocalmemory/storage/migrations/M022_entity_aliases_profile.py +0 -86
  603. package/src/superlocalmemory/storage/migrations/M023_mesh_profile_isolation.py +0 -194
  604. package/src/superlocalmemory/storage/migrations/M024_rbac_users_roles.py +0 -87
  605. package/src/superlocalmemory/storage/migrations/M025_perf_indexes.py +0 -90
  606. package/src/superlocalmemory/storage/migrations/M026_rbac_memberships_fk.py +0 -136
  607. package/src/superlocalmemory/storage/migrations/M027_transferable_patterns_profile.py +0 -163
  608. package/src/superlocalmemory/storage/migrations/M028_fact_entity_associations.py +0 -305
  609. package/src/superlocalmemory/storage/migrations/M029_behavioral_history_indexes.py +0 -137
  610. package/src/superlocalmemory/storage/migrations/M030_entity_explorer_indexes.py +0 -93
  611. package/src/superlocalmemory/storage/migrations/M031_dead_letter_operations.py +0 -80
  612. package/src/superlocalmemory/storage/migrations/M032_write_coordinator_admission.py +0 -188
  613. package/src/superlocalmemory/storage/migrations/M033_projection_transactions.py +0 -148
  614. package/src/superlocalmemory/storage/migrations/M034_obligation_integrity.py +0 -58
  615. package/src/superlocalmemory/storage/migrations/M035_erasure_receipts.py +0 -113
  616. package/src/superlocalmemory/storage/migrations/M036_vector_row_map.py +0 -107
  617. package/src/superlocalmemory/storage/migrations/M037_manifest_hmac_version.py +0 -162
  618. package/src/superlocalmemory/storage/migrations/M038_learning_feedback_channel.py +0 -77
  619. package/src/superlocalmemory/storage/migrations/M039_scene_fact_members.py +0 -137
  620. package/src/superlocalmemory/storage/migrations/M040_agent_experience_receipts.py +0 -254
  621. package/src/superlocalmemory/storage/migrations/M041_external_evidence_receipts.py +0 -189
  622. package/src/superlocalmemory/storage/migrations/M042_correction_case_ledger.py +0 -245
  623. package/src/superlocalmemory/storage/migrations/M043_quarantine_display_summaries.py +0 -512
  624. package/src/superlocalmemory/storage/migrations/M044_play_carries_its_own_evidence.py +0 -127
  625. package/src/superlocalmemory/storage/migrations/M045_fact_outcome_score.py +0 -158
  626. package/src/superlocalmemory/storage/migrations/M046_prospective_memory_has_its_own_name.py +0 -620
  627. package/src/superlocalmemory/storage/migrations/M047_fisher_vectors_are_stored_like_every_other_vector.py +0 -306
  628. package/src/superlocalmemory/storage/migrations/M048_upcoming_holds_only_what_is_upcoming.py +0 -229
  629. package/src/superlocalmemory/storage/migrations/M049_a_schema_version_marker_is_one_row.py +0 -201
  630. package/src/superlocalmemory/storage/migrations/M050_execution_learning_v2.py +0 -70
  631. package/src/superlocalmemory/storage/migrations/__init__.py +0 -103
  632. package/src/superlocalmemory/storage/migrations.py +0 -333
  633. package/src/superlocalmemory/storage/models.py +0 -500
  634. package/src/superlocalmemory/storage/projection_outbox.py +0 -346
  635. package/src/superlocalmemory/storage/quantized_store.py +0 -280
  636. package/src/superlocalmemory/storage/read_connection.py +0 -115
  637. package/src/superlocalmemory/storage/retention_policy.py +0 -860
  638. package/src/superlocalmemory/storage/schema.py +0 -1108
  639. package/src/superlocalmemory/storage/schema_code_graph.py +0 -282
  640. package/src/superlocalmemory/storage/schema_v32.py +0 -382
  641. package/src/superlocalmemory/storage/schema_v3410.py +0 -159
  642. package/src/superlocalmemory/storage/schema_v3411.py +0 -149
  643. package/src/superlocalmemory/storage/schema_v343.py +0 -315
  644. package/src/superlocalmemory/storage/schema_v345.py +0 -109
  645. package/src/superlocalmemory/storage/schema_v347.py +0 -140
  646. package/src/superlocalmemory/storage/sqlite_vectors.py +0 -169
  647. package/src/superlocalmemory/storage/v2_migrator.py +0 -466
  648. package/src/superlocalmemory/storage/write_coordinator.py +0 -949
  649. package/src/superlocalmemory/storage/write_lock.py +0 -88
  650. package/src/superlocalmemory/summaries/__init__.py +0 -37
  651. package/src/superlocalmemory/summaries/base.py +0 -267
  652. package/src/superlocalmemory/summaries/daily_reflection.py +0 -340
  653. package/src/superlocalmemory/summaries/non_answer.py +0 -223
  654. package/src/superlocalmemory/summaries/project_work_log.py +0 -440
  655. package/src/superlocalmemory/summaries/session_summary.py +0 -311
  656. package/src/superlocalmemory/trust/__init__.py +0 -0
  657. package/src/superlocalmemory/trust/gate.py +0 -171
  658. package/src/superlocalmemory/trust/provenance.py +0 -124
  659. package/src/superlocalmemory/trust/scorer.py +0 -413
  660. package/src/superlocalmemory/trust/signals.py +0 -153
  661. package/src/superlocalmemory/ui/assets/slm-icon-white.svg +0 -64
  662. package/src/superlocalmemory/ui/assets/slm-icon.svg +0 -36
  663. package/src/superlocalmemory/ui/css/brain.css +0 -409
  664. package/src/superlocalmemory/ui/css/design-system.css +0 -696
  665. package/src/superlocalmemory/ui/css/legacy-dashboard.css +0 -663
  666. package/src/superlocalmemory/ui/css/neural-glass.css +0 -1599
  667. package/src/superlocalmemory/ui/css/od-bridge.css +0 -158
  668. package/src/superlocalmemory/ui/favicon.svg +0 -36
  669. package/src/superlocalmemory/ui/index.html +0 -1638
  670. package/src/superlocalmemory/ui/js/agents.js +0 -192
  671. package/src/superlocalmemory/ui/js/auto-settings.js +0 -624
  672. package/src/superlocalmemory/ui/js/brain.js +0 -1400
  673. package/src/superlocalmemory/ui/js/clusters.js +0 -326
  674. package/src/superlocalmemory/ui/js/compliance.js +0 -307
  675. package/src/superlocalmemory/ui/js/core.js +0 -566
  676. package/src/superlocalmemory/ui/js/dashboard.js +0 -503
  677. package/src/superlocalmemory/ui/js/event-delegation.js +0 -113
  678. package/src/superlocalmemory/ui/js/events.js +0 -178
  679. package/src/superlocalmemory/ui/js/fact-detail.js +0 -142
  680. package/src/superlocalmemory/ui/js/feedback.js +0 -339
  681. package/src/superlocalmemory/ui/js/graph-event-bus.js +0 -83
  682. package/src/superlocalmemory/ui/js/graph-filters.js +0 -220
  683. package/src/superlocalmemory/ui/js/graph-ui.js +0 -214
  684. package/src/superlocalmemory/ui/js/ide-status.js +0 -115
  685. package/src/superlocalmemory/ui/js/init.js +0 -54
  686. package/src/superlocalmemory/ui/js/knowledge-graph.js +0 -945
  687. package/src/superlocalmemory/ui/js/lifecycle.js +0 -387
  688. package/src/superlocalmemory/ui/js/math-health.js +0 -114
  689. package/src/superlocalmemory/ui/js/memories.js +0 -394
  690. package/src/superlocalmemory/ui/js/memory-chat.js +0 -371
  691. package/src/superlocalmemory/ui/js/memory-timeline.js +0 -265
  692. package/src/superlocalmemory/ui/js/modal.js +0 -733
  693. package/src/superlocalmemory/ui/js/ng-entities.js +0 -298
  694. package/src/superlocalmemory/ui/js/ng-health.js +0 -208
  695. package/src/superlocalmemory/ui/js/ng-ingestion.js +0 -203
  696. package/src/superlocalmemory/ui/js/ng-mesh.js +0 -374
  697. package/src/superlocalmemory/ui/js/ng-shell.js +0 -524
  698. package/src/superlocalmemory/ui/js/ng-skills.js +0 -663
  699. package/src/superlocalmemory/ui/js/od-agents.js +0 -588
  700. package/src/superlocalmemory/ui/js/od-auth-gate.js +0 -257
  701. package/src/superlocalmemory/ui/js/od-backup.js +0 -878
  702. package/src/superlocalmemory/ui/js/od-boundedloops.js +0 -324
  703. package/src/superlocalmemory/ui/js/od-brain.js +0 -1095
  704. package/src/superlocalmemory/ui/js/od-compliance-ext.js +0 -301
  705. package/src/superlocalmemory/ui/js/od-components.js +0 -147
  706. package/src/superlocalmemory/ui/js/od-entities.js +0 -622
  707. package/src/superlocalmemory/ui/js/od-graph.js +0 -776
  708. package/src/superlocalmemory/ui/js/od-health.js +0 -579
  709. package/src/superlocalmemory/ui/js/od-mcp.js +0 -508
  710. package/src/superlocalmemory/ui/js/od-memories.js +0 -1499
  711. package/src/superlocalmemory/ui/js/od-mesh.js +0 -645
  712. package/src/superlocalmemory/ui/js/od-operations.js +0 -1268
  713. package/src/superlocalmemory/ui/js/od-ops-health.js +0 -417
  714. package/src/superlocalmemory/ui/js/od-optimize.js +0 -828
  715. package/src/superlocalmemory/ui/js/od-settings.js +0 -1275
  716. package/src/superlocalmemory/ui/js/od-shell.js +0 -819
  717. package/src/superlocalmemory/ui/js/od-skills.js +0 -600
  718. package/src/superlocalmemory/ui/js/od-team.js +0 -265
  719. package/src/superlocalmemory/ui/js/optimize.js +0 -191
  720. package/src/superlocalmemory/ui/js/profiles.js +0 -362
  721. package/src/superlocalmemory/ui/js/quick-actions.js +0 -334
  722. package/src/superlocalmemory/ui/js/recall-lab.js +0 -373
  723. package/src/superlocalmemory/ui/js/search.js +0 -86
  724. package/src/superlocalmemory/ui/js/settings.js +0 -556
  725. package/src/superlocalmemory/ui/js/timeline.js +0 -62
  726. package/src/superlocalmemory/ui/js/trust-dashboard.js +0 -225
  727. package/src/superlocalmemory/ui/vendor/bootstrap-icons/bootstrap-icons.css +0 -2018
  728. package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
  729. package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
  730. package/src/superlocalmemory/ui/vendor/bootstrap.bundle.min.js +0 -7
  731. package/src/superlocalmemory/ui/vendor/bootstrap.min.css +0 -6
  732. package/src/superlocalmemory/ui/vendor/d3.v7.min.js +0 -2
  733. package/src/superlocalmemory/ui/vendor/graphology-library.min.js +0 -2
  734. package/src/superlocalmemory/ui/vendor/graphology.umd.min.js +0 -2
  735. package/src/superlocalmemory/ui/vendor/inter-ui/inter-variable.min.css +0 -8
  736. package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable-Italic.woff2 +0 -0
  737. package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable.woff2 +0 -0
  738. package/src/superlocalmemory/ui/vendor/sigma.min.js +0 -1
  739. package/src/superlocalmemory/vector/__init__.py +0 -9
  740. package/src/superlocalmemory/vector/lancedb_backend.py +0 -366
@@ -1,769 +0,0 @@
1
- # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under AGPL-3.0-or-later
3
-
4
- """Phase 1 admission gateway — resolve_actor + admit + @admits decorator.
5
-
6
- This module is the single shared admission API for MCP, CLI, and HTTP transports.
7
- HTTP already uses the registry directly (unified_daemon.py:3740); this module
8
- wires the same evaluation to MCP tools and CLI commands.
9
-
10
- INVARIANT: resolve_actor() derives ActorContext from server-side facts only.
11
- Never call it with data from the MCP/CLI request body.
12
-
13
- Key design choices
14
- ------------------
15
- - Personal/single-user mode → OWNER (frictionless). Zero new friction.
16
- - Enterprise mode + no principal → ANONYMOUS → denied for mutations.
17
- - admit() raises AdmissionDenied on deny so the caller can return a clean error.
18
- - @admits(kind) is a thin async decorator for MCP tools.
19
- - coverage_self_check() is called at daemon startup.
20
- - Fail-closed: config.toml present but unreadable → enterprise (not personal).
21
-
22
- Part of SuperLocalMemory V4 | Phase 1: Admission Gateway
23
- """
24
-
25
- from __future__ import annotations
26
-
27
- import functools
28
- import logging
29
- import os
30
- import sqlite3
31
- from typing import TYPE_CHECKING, FrozenSet
32
-
33
- from superlocalmemory.core.actor_context import ActorContext, ActorRole, Transport
34
- from superlocalmemory.core.operation_policy_registry import (
35
- PolicyDecision,
36
- _DEFAULT_REGISTRY,
37
- )
38
- from superlocalmemory.core.operation_request import OperationKind
39
-
40
- if TYPE_CHECKING:
41
- from superlocalmemory.core.config import DeploymentConfig
42
- from superlocalmemory.core.operation_policy_registry import OperationPolicyRegistry
43
-
44
- logger = logging.getLogger(__name__)
45
-
46
- _COMPANY_MODES: frozenset[str] = frozenset({
47
- "company", "remote", "enterprise", "multi-user", "multi_user",
48
- })
49
-
50
-
51
- def _tool_read_only_hint(tool: object) -> object:
52
- """Return the tool's read-only annotation under mcp 1.x or 2.x naming.
53
-
54
- MCP wire protocol uses camelCase ``readOnlyHint``. mcp==2.0.0's
55
- ``ToolAnnotations`` pydantic model stores the field as snake_case
56
- ``read_only_hint`` (alias ``readOnlyHint``) — attribute access by alias
57
- is not available, so a camelCase-only getattr always returns None and
58
- every annotated read tool is misclassified as a mutator.
59
- """
60
- ann = getattr(tool, "annotations", None)
61
- if ann is None:
62
- return None
63
- val = getattr(ann, "readOnlyHint", None)
64
- if val is not None:
65
- return val
66
- return getattr(ann, "read_only_hint", None)
67
-
68
- # ---------------------------------------------------------------------------
69
- # Tool inventory tracking (populated at decoration time by @admits)
70
- # ---------------------------------------------------------------------------
71
-
72
- # Auto-populated as each @admits decorator is applied. Checked at startup.
73
- _GATED_MCP_TOOLS: set[str] = set()
74
-
75
- # Minimal set of MCP mutating tools that MUST be decorated with @admits.
76
- # Extend this set when new mutating tools are added (Tranche B extends it).
77
- # coverage_self_check verifies _REQUIRED_MCP_GATES ⊆ _GATED_MCP_TOOLS.
78
- _REQUIRED_MCP_GATES: frozenset[str] = frozenset({
79
- # Core mutations (tools_core.py)
80
- "remember",
81
- "delete_memory",
82
- "update_memory",
83
- "correct_pattern",
84
- "switch_profile",
85
- "build_graph",
86
- # Forgetting / consolidation (tools_v33.py)
87
- "forget",
88
- "consolidate_cognitive",
89
- "quantize",
90
- # Mode mutations (tools_v3.py)
91
- "set_mode",
92
- # Mesh mutations (tools_mesh.py)
93
- "mesh_send",
94
- "mesh_lock",
95
- "mesh_state",
96
- "mesh_summary",
97
- # Evolution (tools_evolution.py)
98
- "evolve_skill",
99
- # Learning / feedback (tools_learning.py, tools_v28.py, tools_active.py)
100
- "reinforce_assertion",
101
- "contradict_assertion",
102
- "report_outcome",
103
- "report_feedback",
104
- "observe",
105
- "close_session",
106
- # Optimize / cache (tools_optimize.py)
107
- "slm_cache_set",
108
- "slm_compress",
109
- # Code graph (tools_code_graph.py)
110
- "update_code_graph",
111
- # Scoped reads (Tranche C — tools_core.py)
112
- "recall",
113
- "search",
114
- # Tranche E — remaining MCP mutators
115
- "slm_loop_run",
116
- "set_retention_policy",
117
- "compact_memories",
118
- "log_tool_event",
119
- "core_memory",
120
- "run_maintenance",
121
- "reap_processes",
122
- "build_code_graph",
123
- "apply_refactor",
124
- "link_memory_to_code",
125
- # Tranche G — mesh_inbox marks messages as read (POST to mesh broker)
126
- "mesh_inbox",
127
- "fetch",
128
- "list_recent",
129
- "session_init",
130
- })
131
-
132
-
133
- # ---------------------------------------------------------------------------
134
- # Exception
135
- # ---------------------------------------------------------------------------
136
-
137
- class AdmissionDenied(Exception):
138
- """Raised by admit() when the policy evaluation returns allowed=False.
139
-
140
- Callers map this to the appropriate transport error:
141
- - MCP → {"success": False, "error": "not_authorized", "reason": ...}
142
- - CLI → sys.exit(1) + message
143
- - HTTP → already handled via PermissionError→403 in unified_daemon.py
144
- """
145
-
146
- def __init__(self, decision: PolicyDecision) -> None:
147
- super().__init__(decision.reason)
148
- self.decision: PolicyDecision = decision
149
-
150
-
151
- # ---------------------------------------------------------------------------
152
- # Deployment config resolution (fail-closed on present-but-unreadable)
153
- # ---------------------------------------------------------------------------
154
-
155
- def _resolve_deployment() -> "DeploymentConfig":
156
- """Load DeploymentConfig. Fail-closed when config.toml is present but unreadable.
157
-
158
- Distinction:
159
- - config.toml absent → legitimate fresh personal install → PERSONAL (frictionless)
160
- - config.toml present + unreadable/corrupt → unknown enterprise state → ENTERPRISE
161
- - config.toml present + readable → use canonical loader result
162
- """
163
- from superlocalmemory.core.config import DEPLOYMENT_ENTERPRISE, DEPLOYMENT_PERSONAL
164
-
165
- # Step 1: resolve the expected config path (same root as load_deployment_config).
166
- try:
167
- from superlocalmemory.infra.data_root import state_path
168
- config_path = state_path("config.toml")
169
- config_exists = config_path.exists()
170
- except Exception as exc:
171
- logger.debug("admission: cannot resolve config path, personal default: %s", exc)
172
- return DEPLOYMENT_PERSONAL
173
-
174
- # Step 2: absent → personal (fresh install, no config ever written).
175
- if not config_exists:
176
- return DEPLOYMENT_PERSONAL
177
-
178
- # Step 3: present → probe raw to detect corrupt/unreadable before delegating.
179
- try:
180
- import tomllib
181
- raw = config_path.read_text(encoding="utf-8")
182
- parsed_toml = tomllib.loads(raw) # raises on corrupt TOML
183
- except Exception as exc:
184
- # File exists but cannot be parsed → fail-closed (treat as enterprise).
185
- logger.warning(
186
- "admission: config.toml present but unreadable — fail-closed "
187
- "(treating as enterprise). Cause: %s", exc,
188
- )
189
- return DEPLOYMENT_ENTERPRISE
190
-
191
- # Step 4: readable → delegate to canonical loader (handles mode/fields).
192
- try:
193
- from superlocalmemory.core.config import load_deployment_config
194
- result = load_deployment_config(config_toml_path=config_path)
195
- except Exception as exc: # noqa: BLE001
196
- # config.toml exists and parsed as TOML; only its interpretation failed.
197
- # Returning PERSONAL here would hand owner access to a store that may
198
- # well be enterprise. Step 2 already returned PERSONAL for the fresh
199
- # install with no config at all, which is the case that needs to stay
200
- # frictionless.
201
- logger.warning(
202
- "admission: config.toml is present but could not be interpreted "
203
- "(%s) -- fail-closed (treating as enterprise).", exc,
204
- )
205
- return DEPLOYMENT_ENTERPRISE
206
-
207
- # D1 fail-closed: [deployment] section present but mode is unrecognized or
208
- # absent means someone tried to configure enterprise and a typo/omission
209
- # should not silently grant personal (OWNER) access on an enterprise box.
210
- # Explicit mode="personal" is a deliberate choice — honour it.
211
- # Explicit mode="enterprise" → canonical loader already returned ENTERPRISE.
212
- _KNOWN_MODES = ("personal", "enterprise")
213
- dep_section = parsed_toml.get("deployment", {})
214
- declared_mode = str(dep_section.get("mode", "")).strip().lower()
215
- if "deployment" in parsed_toml and declared_mode not in _KNOWN_MODES:
216
- logger.warning(
217
- "admission: config.toml has [deployment] section but mode %r is "
218
- "unrecognized/absent — fail-closed → ENTERPRISE.", declared_mode or "<missing>",
219
- )
220
- return DEPLOYMENT_ENTERPRISE
221
- return result
222
-
223
-
224
- # ---------------------------------------------------------------------------
225
- # resolve_actor
226
- # ---------------------------------------------------------------------------
227
-
228
- def resolve_actor(
229
- transport: Transport,
230
- *,
231
- profile: str = "",
232
- principal: str = "",
233
- session: str = "",
234
- tier: str = "personal",
235
- mode: str = "personal",
236
- client_host: str = "",
237
- roles: FrozenSet[ActorRole] | None = None,
238
- ) -> ActorContext:
239
- """Build a server-derived ActorContext for MCP or CLI transport.
240
-
241
- Rules
242
- -----
243
- - Personal tier (default) → OWNER, no authentication required.
244
- This preserves the existing single-user UX with zero new friction.
245
- - Enterprise tier + no principal → ANONYMOUS.
246
- Mutations will be denied (authentication_required) by admit().
247
- - Enterprise tier + principal → use supplied roles (default: MEMBER).
248
-
249
- Parameters
250
- ----------
251
- transport : MCP, CLI, INTERNAL, etc.
252
- profile : Active profile id (metadata only).
253
- principal : Authenticated principal id (from session store, never from
254
- request body). Empty string → anonymous.
255
- session : Session token (only the first 16 hex chars are stored).
256
- tier : Deployment tier: "personal" or "enterprise".
257
- mode : Deployment mode string; "company"/"remote"/"enterprise" are
258
- treated as enterprise. Checked in addition to ``tier``.
259
- client_host : Resolved remote address (for is_local check).
260
- roles : Explicit role set for authenticated enterprise actor.
261
- When None, defaults to {ActorRole.MEMBER}.
262
- """
263
- is_enterprise = tier == "enterprise" or mode in _COMPANY_MODES
264
-
265
- if not is_enterprise:
266
- return ActorContext(
267
- principal_id="local-operator",
268
- roles=frozenset({ActorRole.OWNER}),
269
- active_profile_id=profile,
270
- transport=transport,
271
- client_host=client_host,
272
- )
273
-
274
- if not principal:
275
- return ActorContext(
276
- principal_id="",
277
- roles=frozenset({ActorRole.ANONYMOUS}),
278
- active_profile_id=profile,
279
- transport=transport,
280
- client_host=client_host,
281
- )
282
-
283
- effective_roles: FrozenSet[ActorRole] = (
284
- roles if roles is not None else frozenset({ActorRole.MEMBER})
285
- )
286
- # Store the SHA-256 prefix of the session token (matching the canonical HTTP
287
- # actor), never the raw token material, for audit-log attribution only.
288
- import hashlib as _hashlib
289
-
290
- _session_hash = (
291
- _hashlib.sha256(session.encode("utf-8")).hexdigest()[:16] if session else ""
292
- )
293
- return ActorContext(
294
- principal_id=principal,
295
- roles=effective_roles,
296
- active_profile_id=profile,
297
- transport=transport,
298
- client_host=client_host,
299
- session_token_hash=_session_hash,
300
- )
301
-
302
-
303
- # ---------------------------------------------------------------------------
304
- # admit
305
- # ---------------------------------------------------------------------------
306
-
307
- def admit(
308
- kind: OperationKind,
309
- actor: ActorContext,
310
- *,
311
- resource_ids: tuple[str, ...] = (),
312
- scope: str | None = None,
313
- mode: str = "local",
314
- registry: "OperationPolicyRegistry | None" = None,
315
- ) -> PolicyDecision:
316
- """Evaluate kind + actor against the policy registry.
317
-
318
- Raises AdmissionDenied on deny. Returns PolicyDecision on allow.
319
-
320
- Parameters
321
- ----------
322
- kind : Operation being requested.
323
- actor : Server-derived ActorContext (never from request body).
324
- resource_ids : Resource identifiers for future ownership checks.
325
- scope : Scope label for future scoped-read checks.
326
- mode : Deployment mode string forwarded to registry.evaluate().
327
- "local"/"personal" → fail-open for unknown kinds.
328
- "company"/"remote"/"enterprise" → fail-closed.
329
- registry : Override the default registry (for testing).
330
- """
331
- reg = registry if registry is not None else _DEFAULT_REGISTRY
332
- decision = reg.evaluate(kind, actor, mode)
333
- if not decision.allowed:
334
- raise AdmissionDenied(decision)
335
- return decision
336
-
337
-
338
- # ---------------------------------------------------------------------------
339
- # @admits decorator for async MCP tools
340
- # ---------------------------------------------------------------------------
341
-
342
-
343
- # ---------------------------------------------------------------------------
344
- # Company mode has two switches, and this is where they become one
345
- # ---------------------------------------------------------------------------
346
-
347
- #: Environment variable carrying the caller's user session over a transport that
348
- #: has no request to put a header on. The dashboard issues the same token, so
349
- #: this is not a second credential system -- it is the only channel the MCP
350
- #: surface offers for presenting the one that already exists.
351
- _SESSION_ENV = "SLM_USER_SESSION"
352
-
353
- _RBAC_ROLE_TO_ACTOR = {
354
- "admin": ActorRole.ADMIN,
355
- "member": ActorRole.MEMBER,
356
- "viewer": ActorRole.VIEWER,
357
- }
358
-
359
-
360
- def _rbac_engine():
361
- """The workspace's role store, or None when there is not one.
362
-
363
- Built from the data root rather than from an HTTP app state, because the
364
- callers here have no request. Failures return None, which then reads as
365
- "personal mode" -- safe, because a workspace with no role store has no roles
366
- to enforce.
367
- """
368
- try:
369
- from superlocalmemory.access.rbac import RbacEngine
370
- from superlocalmemory.infra.data_root import canonical_data_root
371
-
372
- path = canonical_data_root() / "memory.db"
373
- if not path.exists():
374
- return None
375
- return RbacEngine(str(path))
376
- except Exception as exc: # noqa: BLE001
377
- logger.debug("admission: no role store available: %s", exc)
378
- return None
379
-
380
-
381
- def _company_mode_active(deployment) -> bool:
382
- """Whether a login is required, by EITHER of the two switches.
383
-
384
- THE DEFECT THIS CLOSES
385
-
386
- "Company mode" was two independent settings that nobody had joined up:
387
- ``deployment`` in config.toml, which this module read, and ``require_login``
388
- in the workspace's own settings, which the dashboard toggle writes and which
389
- the HTTP routes read. Turning company mode on from the dashboard therefore
390
- changed what HTTP would allow and changed nothing here.
391
-
392
- Measured on a real store: with ``require_login`` on, two users configured,
393
- and the viewer's role denying WRITE, an MCP write resolved to
394
- ``local-operator`` with role ``owner`` and succeeded -- while the same write
395
- over HTTP returned 401. The role check was not bypassed by a missing call;
396
- it was bypassed because this path was still being told the workspace was
397
- personal.
398
-
399
- Either switch now means the same thing on every transport.
400
- """
401
- if getattr(deployment, "is_enterprise", False):
402
- return True
403
- rbac = _rbac_engine()
404
- if rbac is None:
405
- return False
406
- try:
407
- return bool(rbac.require_login())
408
- except sqlite3.OperationalError as exc:
409
- # "No such table" means the role tables were never created, which means
410
- # roles were never set up, which is a personal install. Failing closed on
411
- # THIS is not caution -- it is refusing every write on every store that
412
- # has never used company mode, which is nearly all of them. It was caught
413
- # by an existing test whose second MCP write started failing once a store
414
- # file appeared in the data root.
415
- if "no such table" in str(exc).lower():
416
- logger.debug("admission: no role tables; personal workspace")
417
- return False
418
- logger.warning(
419
- "admission: the login policy is unreadable (%s); treating the "
420
- "workspace as requiring one", exc,
421
- )
422
- return True
423
- except Exception as exc: # noqa: BLE001 -- an unreadable policy is not a licence
424
- logger.warning(
425
- "admission: cannot read the login policy (%s); treating the "
426
- "workspace as requiring one", exc,
427
- )
428
- return True
429
-
430
-
431
- def _target_profile(explicit: str = "") -> str:
432
- """The workspace a call will actually touch.
433
-
434
- An explicit argument wins when the caller supplies one. Otherwise this reads
435
- the same ``profiles.json`` the engine and the HTTP layer read, because that
436
- is where the write is going to land.
437
-
438
- THE DEFECT THIS CLOSES
439
-
440
- The role check used to key off ``kwargs.get("profile_id")``. ``remember``
441
- has no such parameter, so every role lookup resolved against ``default``
442
- while the write went to whichever workspace was active. A user who is an
443
- admin on ``default`` and a viewer on ``team`` passed the check on
444
- ``default`` and wrote to ``team`` -- which HTTP would have refused.
445
- """
446
- name = (explicit or "").strip()
447
- if name:
448
- return name
449
- try:
450
- from superlocalmemory.server.profile_runtime import current_request_profile
451
-
452
- runtime = current_request_profile()
453
- if runtime:
454
- return str(runtime)
455
- except Exception as exc: # noqa: BLE001 -- no request context is normal off HTTP
456
- logger.debug("admission: no request profile in scope: %s", exc)
457
- try:
458
- import json as _json
459
-
460
- from superlocalmemory.infra.data_root import canonical_data_root
461
-
462
- config_file = canonical_data_root() / "profiles.json"
463
- if config_file.exists():
464
- data = _json.loads(config_file.read_text(encoding="utf-8"))
465
- active = str(data.get("active_profile", "") or "").strip()
466
- if active:
467
- return active
468
- except Exception as exc: # noqa: BLE001
469
- logger.debug("admission: cannot read the active workspace: %s", exc)
470
- return "default"
471
-
472
-
473
- def _session_principal(profile: str) -> tuple[str, str, FrozenSet[ActorRole] | None]:
474
- """Resolve the caller from a session token in the environment.
475
-
476
- Returns ``(principal_id, raw_token, roles)``. An empty principal means the
477
- caller could not be identified, which ``resolve_actor`` turns into ANONYMOUS
478
- and ``admit`` then denies -- so an unset or expired token fails closed.
479
- """
480
- token = os.environ.get(_SESSION_ENV, "").strip()
481
- if not token:
482
- return "", "", None
483
- rbac = _rbac_engine()
484
- if rbac is None:
485
- return "", "", None
486
- try:
487
- user = rbac.resolve_session(token)
488
- except Exception as exc: # noqa: BLE001
489
- logger.debug("admission: session lookup failed: %s", exc)
490
- return "", "", None
491
- if not user:
492
- return "", "", None
493
- role = None
494
- try:
495
- role = rbac.get_role(user["user_id"], profile or "default")
496
- except Exception as exc: # noqa: BLE001
497
- logger.debug("admission: role lookup failed: %s", exc)
498
- # No membership on this workspace is not the same as MEMBER. Falling back to
499
- # a write-capable default here would hand every authenticated user write
500
- # access to every workspace on the machine.
501
- actor_role = _RBAC_ROLE_TO_ACTOR.get(
502
- getattr(role, "value", role) if role is not None else "", None,
503
- )
504
- if actor_role is None:
505
- return user["user_id"], token, frozenset({ActorRole.ANONYMOUS})
506
- return user["user_id"], token, frozenset({actor_role})
507
-
508
-
509
- def admits(kind: OperationKind):
510
- """Decorator that gates an async MCP tool function via the policy registry.
511
-
512
- Usage (inside register_*_tools):
513
-
514
- @server.tool()
515
- @admits(OperationKind.REMEMBER)
516
- async def remember(content: str, ...) -> dict:
517
- ...
518
-
519
- Also registers the tool name in _GATED_MCP_TOOLS at decoration time,
520
- enabling coverage_self_check() to verify tool inventory at startup.
521
-
522
- On AdmissionDenied the decorator returns the error dict directly without
523
- calling the wrapped function.
524
- """
525
- def decorator(fn):
526
- _GATED_MCP_TOOLS.add(fn.__name__) # register at decoration time
527
-
528
- @functools.wraps(fn)
529
- async def wrapper(*args, **kwargs):
530
- deployment = _resolve_deployment()
531
- # Either switch means company mode. Reading only the config file is
532
- # what let a dashboard toggle change HTTP and leave this transport
533
- # writing as the machine owner.
534
- company = _company_mode_active(deployment)
535
- tier = "enterprise" if company else "personal"
536
- mode = "company" if company else "local"
537
- principal, token, roles = ("", "", None)
538
- if company:
539
- principal, token, roles = _session_principal(
540
- _target_profile(kwargs.get("profile_id", "") or ""),
541
- )
542
- actor = resolve_actor(
543
- Transport.MCP, tier=tier, mode=mode,
544
- principal=principal, session=token, roles=roles,
545
- )
546
- try:
547
- admit(kind, actor, mode=mode)
548
- except AdmissionDenied as exc:
549
- return {
550
- "success": False,
551
- "error": "not_authorized",
552
- "reason": exc.decision.reason,
553
- }
554
- return await fn(*args, **kwargs)
555
- return wrapper
556
- return decorator
557
-
558
-
559
- # ---------------------------------------------------------------------------
560
- # CLI gate helper
561
- # ---------------------------------------------------------------------------
562
-
563
- def gate_cli_mutation(
564
- kind: OperationKind,
565
- *,
566
- principal: str = "",
567
- roles: FrozenSet[ActorRole] | None = None,
568
- profile: str = "",
569
- ) -> None:
570
- """Gate a CLI mutation command. Exits with code 1 if denied.
571
-
572
- Call this at the top of any CLI mutation handler that bypasses the daemon.
573
- In personal mode this is a no-op (OWNER always admitted). In enterprise
574
- mode without a principal it exits with a clear message.
575
-
576
- Parameters
577
- ----------
578
- kind : Operation being performed.
579
- principal : Authenticated CLI principal (from session store / login token).
580
- roles : Explicit roles for an authenticated enterprise user.
581
- profile : Workspace the command will touch. Empty means the active one.
582
- """
583
- import sys
584
- deployment = _resolve_deployment()
585
- # Either switch means company mode -- the same rule the MCP gate uses. This
586
- # gate used to read config.toml alone, so turning per-user access on from
587
- # the dashboard changed HTTP and MCP and left every CLI write running as the
588
- # machine owner.
589
- company = _company_mode_active(deployment)
590
- tier = "enterprise" if company else "personal"
591
- mode = "company" if company else "local"
592
- session = ""
593
- if company and not principal:
594
- # A CLI caller identifies itself the same way an MCP caller does. With
595
- # no token the principal stays empty, resolve_actor returns ANONYMOUS,
596
- # and admit denies -- which is the intended answer for an unauthenticated
597
- # write on a workspace that requires a login.
598
- principal, session, resolved_roles = _session_principal(
599
- _target_profile(profile),
600
- )
601
- if roles is None:
602
- roles = resolved_roles
603
- actor = resolve_actor(
604
- Transport.CLI,
605
- tier=tier,
606
- mode=mode,
607
- principal=principal,
608
- session=session,
609
- roles=roles,
610
- )
611
- try:
612
- admit(kind, actor, mode=mode)
613
- except AdmissionDenied as exc:
614
- # Name something the reader can actually do. This used to say
615
- # "log in with 'slm login'", and there is no such command -- so the one
616
- # instruction the message gave was a dead end.
617
- print(
618
- f"[slm] Operation denied ({exc.decision.reason}). "
619
- "This workspace requires a signed-in user. Sign in on the dashboard "
620
- "(slm dashboard), copy your session token, and put it in the "
621
- "SLM_USER_SESSION environment variable -- or ask whoever "
622
- "administers this workspace for access.",
623
- flush=True,
624
- )
625
- sys.exit(1)
626
-
627
-
628
- # ---------------------------------------------------------------------------
629
- # Startup coverage self-check (non-vacuous)
630
- # ---------------------------------------------------------------------------
631
-
632
- def coverage_self_check(
633
- deployment: "DeploymentConfig",
634
- registry: "OperationPolicyRegistry | None" = None,
635
- server: "object | None" = None,
636
- ) -> None:
637
- """Assert comprehensive policy coverage at daemon startup.
638
-
639
- Checks:
640
- 1. Every OperationKind has a registered policy (existing check).
641
- 2. No policy has an empty allowed_transports set (unreachable = bug).
642
- 3. Every tool in _REQUIRED_MCP_GATES appears in _GATED_MCP_TOOLS.
643
- 4. (F1) Dynamic: every mutating tool in server._tool_manager._tools
644
- that is NOT flagged readOnlyHint=True must be in _GATED_MCP_TOOLS.
645
-
646
- In personal/local mode: logs warnings for any gap (non-fatal).
647
- In enterprise mode: raises RuntimeError on the first gap (fatal startup).
648
-
649
- Parameters
650
- ----------
651
- deployment : Loaded DeploymentConfig (from unified_daemon startup).
652
- registry : Override the default registry (for testing).
653
- server : Optional FastMCP server; when supplied, its tool registry
654
- is enumerated for check 4 (dynamic mutator coverage).
655
- """
656
- reg = registry if registry is not None else _DEFAULT_REGISTRY
657
- is_enterprise = deployment.is_enterprise
658
- messages: list[str] = []
659
-
660
- # Check 1: every OperationKind has a policy entry.
661
- cov = reg.coverage()
662
- missing_kinds = [
663
- kind.value
664
- for kind in OperationKind
665
- if not cov.get(kind.value, {}).get("has_policy", False)
666
- ]
667
- if missing_kinds:
668
- messages.append(f"policy coverage gap — no policy for: {missing_kinds}")
669
-
670
- # Check 2: no policy has empty allowed_transports (unreachable).
671
- empty_transport_kinds = [
672
- info["kind"]
673
- for info in cov.values()
674
- if info.get("has_policy") and not info.get("has_transports", True)
675
- ]
676
- if empty_transport_kinds:
677
- messages.append(
678
- f"empty_transports in policies for: {empty_transport_kinds} "
679
- "(no reachable transport — these operations can never be invoked)"
680
- )
681
-
682
- # Check 3: tool inventory — every required MCP gate is wired.
683
- ungated = sorted(_REQUIRED_MCP_GATES - _GATED_MCP_TOOLS)
684
- if ungated:
685
- messages.append(f"ungated MCP tools (missing @admits): {ungated}")
686
-
687
- # Check 4 (F1): dynamic discovery — enumerate server tool registry and flag
688
- # any mutating tool (readOnlyHint / read_only_hint != True) not in
689
- # _GATED_MCP_TOOLS. See _tool_read_only_hint for mcp 2.0 naming.
690
- if server is not None:
691
- try:
692
- tool_dict = server._tool_manager._tools # type: ignore[attr-defined]
693
- dynamic_ungated = sorted(
694
- name
695
- for name, tool in tool_dict.items()
696
- if name not in _GATED_MCP_TOOLS
697
- and _tool_read_only_hint(tool) is not True
698
- )
699
- if dynamic_ungated:
700
- messages.append(
701
- f"dynamic ungated MCP mutators (not in _GATED_MCP_TOOLS): {dynamic_ungated}"
702
- )
703
- except AttributeError:
704
- logger.debug(
705
- "admission: server does not expose _tool_manager._tools — skipping dynamic check"
706
- )
707
-
708
- if not messages:
709
- logger.debug("admission: coverage self-check passed (%d kinds)", len(list(OperationKind)))
710
- return
711
-
712
- for msg in messages:
713
- full = f"admission: {msg}"
714
- if is_enterprise:
715
- raise RuntimeError(full)
716
- logger.warning(full)
717
-
718
-
719
- def enforce_read_scope(
720
- include_global: "bool | None",
721
- include_shared: "bool | None",
722
- *,
723
- registry: "OperationPolicyRegistry | None" = None,
724
- ) -> "tuple[bool | None, bool | None]":
725
- """Clamp cross-profile read flags to the RECALL policy's ``allow_cross_profile``.
726
-
727
- In personal mode the OWNER is unrestricted — flags pass through unchanged.
728
- In enterprise mode with ``allow_cross_profile=False`` (the default), any
729
- explicit ``True`` is silently clamped to ``False`` to prevent client
730
- escalation beyond the configured scope authority. ``None`` (not specified)
731
- is left alone so the server default applies.
732
- """
733
- deployment = _resolve_deployment()
734
- # Both switches, for the same reason the write gates read both: a dashboard
735
- # toggle used to leave this path unclamped, so a viewer could ask for
736
- # include_global=True over MCP and pull another workspace's facts into the
737
- # candidate set while HTTP refused the same request.
738
- if not _company_mode_active(deployment):
739
- return include_global, include_shared
740
-
741
- reg = registry if registry is not None else _DEFAULT_REGISTRY
742
- from superlocalmemory.core.operation_request import OperationKind as _OK
743
- policy = reg._policies.get(_OK.RECALL)
744
- if policy is None or policy.allow_cross_profile:
745
- return include_global, include_shared
746
-
747
- clamped_global = False if include_global is True else include_global
748
- clamped_shared = False if include_shared is True else include_shared
749
- if clamped_global is not include_global or clamped_shared is not include_shared:
750
- logger.debug(
751
- "admission: enforce_read_scope clamped cross-profile flags "
752
- "(include_global=%s→%s, include_shared=%s→%s)",
753
- include_global, clamped_global, include_shared, clamped_shared,
754
- )
755
- return clamped_global, clamped_shared
756
-
757
-
758
- __all__ = [
759
- "AdmissionDenied",
760
- "admit",
761
- "admits",
762
- "coverage_self_check",
763
- "enforce_read_scope",
764
- "gate_cli_mutation",
765
- "resolve_actor",
766
- "_resolve_deployment",
767
- "_GATED_MCP_TOOLS",
768
- "_REQUIRED_MCP_GATES",
769
- ]