superlocalmemory 4.0.10 → 4.1.2

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 (145) hide show
  1. package/.claude-plugin/marketplace.json +12 -2
  2. package/CHANGELOG.md +244 -0
  3. package/README.md +40 -75
  4. package/package.json +6 -3
  5. package/plugin/.claude-plugin/plugin.json +2 -2
  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 +4 -4
  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 +2 -2
  17. package/plugin/skills/slm-mesh/SKILL.md +1 -1
  18. package/plugin/skills/slm-profile/SKILL.md +5 -5
  19. package/plugin/skills/slm-recall/SKILL.md +102 -15
  20. package/plugin/skills/slm-remember/SKILL.md +35 -3
  21. package/plugin/skills/slm-scope/SKILL.md +1 -1
  22. package/plugin/skills/slm-session/SKILL.md +29 -3
  23. package/plugin/skills/slm-status/SKILL.md +1 -1
  24. package/plugin-src/rules/AGENTS.md +16 -8
  25. package/plugin-src/skills/slm-cache/SKILL.md +1 -1
  26. package/plugin-src/skills/slm-compress/SKILL.md +1 -1
  27. package/plugin-src/skills/slm-governance/SKILL.md +1 -1
  28. package/plugin-src/skills/slm-graph/SKILL.md +1 -1
  29. package/plugin-src/skills/slm-loop/SKILL.md +2 -2
  30. package/plugin-src/skills/slm-mesh/SKILL.md +1 -1
  31. package/plugin-src/skills/slm-profile/SKILL.md +5 -5
  32. package/plugin-src/skills/slm-recall/SKILL.md +102 -15
  33. package/plugin-src/skills/slm-remember/SKILL.md +35 -3
  34. package/plugin-src/skills/slm-scope/SKILL.md +1 -1
  35. package/plugin-src/skills/slm-session/SKILL.md +29 -3
  36. package/plugin-src/skills/slm-status/SKILL.md +1 -1
  37. package/pyproject.toml +1 -1
  38. package/src/superlocalmemory/__init__.py +1 -1
  39. package/src/superlocalmemory/cli/commands.py +357 -18
  40. package/src/superlocalmemory/cli/daemon.py +30 -0
  41. package/src/superlocalmemory/cli/db_migrate.py +71 -1
  42. package/src/superlocalmemory/cli/gdpr_cmd.py +15 -2
  43. package/src/superlocalmemory/cli/main.py +24 -2
  44. package/src/superlocalmemory/code_graph/database.py +44 -0
  45. package/src/superlocalmemory/compliance/gdpr.py +449 -39
  46. package/src/superlocalmemory/core/admission.py +231 -11
  47. package/src/superlocalmemory/core/backend_orchestrator.py +190 -84
  48. package/src/superlocalmemory/core/config.py +90 -11
  49. package/src/superlocalmemory/core/consolidation_engine.py +34 -0
  50. package/src/superlocalmemory/core/engine.py +140 -11
  51. package/src/superlocalmemory/core/graph_analyzer.py +76 -112
  52. package/src/superlocalmemory/core/graph_metrics.py +597 -0
  53. package/src/superlocalmemory/core/graph_pruner.py +121 -0
  54. package/src/superlocalmemory/core/maintenance_scheduler.py +205 -0
  55. package/src/superlocalmemory/core/mode_capability.py +111 -0
  56. package/src/superlocalmemory/core/ollama_validator.py +315 -0
  57. package/src/superlocalmemory/core/projection_drain.py +380 -0
  58. package/src/superlocalmemory/core/recall_pipeline.py +390 -3
  59. package/src/superlocalmemory/core/recall_worker.py +6 -3
  60. package/src/superlocalmemory/core/scale_autopromote.py +196 -0
  61. package/src/superlocalmemory/core/scale_engine.py +16 -2
  62. package/src/superlocalmemory/core/score_contract.py +21 -1
  63. package/src/superlocalmemory/core/session_identity.py +85 -0
  64. package/src/superlocalmemory/core/status_contract.py +108 -0
  65. package/src/superlocalmemory/core/worker_pool.py +4 -4
  66. package/src/superlocalmemory/core/working_memory.py +288 -0
  67. package/src/superlocalmemory/encoding/cognitive_consolidator.py +36 -6
  68. package/src/superlocalmemory/encoding/context_generator.py +1 -1
  69. package/src/superlocalmemory/encoding/entity_resolver.py +38 -0
  70. package/src/superlocalmemory/encoding/fact_extractor.py +18 -14
  71. package/src/superlocalmemory/encoding/prospective_markers.py +262 -0
  72. package/src/superlocalmemory/encoding/type_router.py +12 -12
  73. package/src/superlocalmemory/evolution/mutation_generator.py +30 -4
  74. package/src/superlocalmemory/graph/cozo_adjacency.py +122 -0
  75. package/src/superlocalmemory/graph/cozo_backend.py +103 -138
  76. package/src/superlocalmemory/hooks/portable_kit.py +10 -2
  77. package/src/superlocalmemory/learning/bandit.py +43 -0
  78. package/src/superlocalmemory/learning/consolidation_worker.py +54 -0
  79. package/src/superlocalmemory/learning/database.py +60 -3
  80. package/src/superlocalmemory/learning/entity_compiler.py +21 -58
  81. package/src/superlocalmemory/learning/feedback.py +3 -1
  82. package/src/superlocalmemory/learning/outcomes.py +47 -16
  83. package/src/superlocalmemory/learning/pattern_miner.py +28 -3
  84. package/src/superlocalmemory/learning/pattern_miner_constants.py +43 -0
  85. package/src/superlocalmemory/learning/pcos.py +291 -0
  86. package/src/superlocalmemory/learning/reward_from_outcomes.py +365 -0
  87. package/src/superlocalmemory/learning/reward_proxy.py +100 -10
  88. package/src/superlocalmemory/learning/signal_kinds.py +79 -0
  89. package/src/superlocalmemory/mcp/profiles.py +14 -2
  90. package/src/superlocalmemory/mcp/tools_active.py +2 -1
  91. package/src/superlocalmemory/mcp/tools_core.py +31 -3
  92. package/src/superlocalmemory/mcp/tools_v28.py +20 -1
  93. package/src/superlocalmemory/parameterization/pattern_extractor.py +14 -1
  94. package/src/superlocalmemory/parameterization/soft_prompt_generator.py +98 -0
  95. package/src/superlocalmemory/retrieval/bm25_channel.py +64 -3
  96. package/src/superlocalmemory/retrieval/channel_status.py +117 -0
  97. package/src/superlocalmemory/retrieval/engine.py +106 -11
  98. package/src/superlocalmemory/retrieval/entity_channel.py +210 -256
  99. package/src/superlocalmemory/retrieval/graph_adjacency.py +219 -0
  100. package/src/superlocalmemory/retrieval/scope_policy.py +20 -0
  101. package/src/superlocalmemory/retrieval/semantic_channel.py +47 -5
  102. package/src/superlocalmemory/retrieval/spreading.py +288 -0
  103. package/src/superlocalmemory/server/api.py +24 -5
  104. package/src/superlocalmemory/server/bandit_loops.py +17 -1
  105. package/src/superlocalmemory/server/rbac_enforce.py +26 -6
  106. package/src/superlocalmemory/server/recall_health.py +87 -10
  107. package/src/superlocalmemory/server/recall_serializer.py +9 -0
  108. package/src/superlocalmemory/server/routes/behavioral.py +75 -10
  109. package/src/superlocalmemory/server/routes/compliance.py +98 -18
  110. package/src/superlocalmemory/server/routes/config_api.py +186 -4
  111. package/src/superlocalmemory/server/routes/evolution.py +178 -0
  112. package/src/superlocalmemory/server/routes/ingest.py +8 -0
  113. package/src/superlocalmemory/server/routes/learning_telemetry.py +2 -1
  114. package/src/superlocalmemory/server/routes/memories.py +49 -7
  115. package/src/superlocalmemory/server/routes/timeline.py +4 -0
  116. package/src/superlocalmemory/server/routes/v3_api.py +191 -15
  117. package/src/superlocalmemory/server/ui.py +20 -4
  118. package/src/superlocalmemory/server/unified_daemon.py +241 -7
  119. package/src/superlocalmemory/storage/_migration_internals.py +54 -2
  120. package/src/superlocalmemory/storage/_schema_version.py +24 -3
  121. package/src/superlocalmemory/storage/database.py +477 -59
  122. package/src/superlocalmemory/storage/embedding_codec.py +71 -0
  123. package/src/superlocalmemory/storage/lineage_retention.py +236 -0
  124. package/src/superlocalmemory/storage/logical_edges.py +43 -2
  125. package/src/superlocalmemory/storage/migration_runner.py +119 -0
  126. package/src/superlocalmemory/storage/migrations/M043_quarantine_display_summaries.py +60 -36
  127. package/src/superlocalmemory/storage/migrations/M044_play_carries_its_own_evidence.py +127 -0
  128. package/src/superlocalmemory/storage/migrations/M045_fact_outcome_score.py +158 -0
  129. package/src/superlocalmemory/storage/migrations/M046_prospective_memory_has_its_own_name.py +620 -0
  130. package/src/superlocalmemory/storage/migrations/M047_fisher_vectors_are_stored_like_every_other_vector.py +306 -0
  131. package/src/superlocalmemory/storage/migrations/M048_upcoming_holds_only_what_is_upcoming.py +207 -0
  132. package/src/superlocalmemory/storage/migrations/M049_a_schema_version_marker_is_one_row.py +201 -0
  133. package/src/superlocalmemory/storage/migrations.py +18 -2
  134. package/src/superlocalmemory/storage/models.py +40 -1
  135. package/src/superlocalmemory/storage/projection_outbox.py +346 -0
  136. package/src/superlocalmemory/storage/retention_policy.py +860 -0
  137. package/src/superlocalmemory/storage/schema.py +35 -1
  138. package/src/superlocalmemory/storage/write_coordinator.py +19 -2
  139. package/src/superlocalmemory/trust/scorer.py +43 -1
  140. package/src/superlocalmemory/ui/index.html +9 -18
  141. package/src/superlocalmemory/ui/js/event-delegation.js +12 -1
  142. package/src/superlocalmemory/ui/js/od-health.js +28 -6
  143. package/src/superlocalmemory/ui/js/od-memories.js +19 -0
  144. package/src/superlocalmemory/ui/js/od-settings.js +87 -1
  145. package/src/superlocalmemory/ui/js/recall-lab.js +78 -3
@@ -427,9 +427,14 @@ def _cmd_gdpr_erase(args: Namespace) -> None:
427
427
  sys.exit(1)
428
428
 
429
429
  complete = counts.get("erasure_complete", 0)
430
+ # Whether it can be SHOWN to have happened is a separate answer, and
431
+ # printing COMPLETE while the tamper-evident receipt failed to persist is
432
+ # how the command line came to disagree with the API about the same erasure.
433
+ provable = counts.get("erasure_provable", complete)
430
434
  result_data = {
431
435
  "profile": profile,
432
436
  "erasure_complete": bool(complete),
437
+ "erasure_provable": bool(provable),
433
438
  "counts": counts,
434
439
  "note": (
435
440
  "Erasure recorded in audit_chain.db. "
@@ -441,7 +446,15 @@ def _cmd_gdpr_erase(args: Namespace) -> None:
441
446
  if use_json:
442
447
  _print_json(_json_envelope("gdpr-erase", data=result_data))
443
448
  else:
444
- status_str = "COMPLETE" if complete else "INCOMPLETE (check counts)"
449
+ if not complete:
450
+ status_str = "INCOMPLETE (check counts)"
451
+ elif not provable:
452
+ status_str = (
453
+ "COMPLETE, BUT NOT PROVABLE — the data is gone and the "
454
+ "tamper-evident receipt did not persist"
455
+ )
456
+ else:
457
+ status_str = "COMPLETE"
445
458
  print(f"Art.17 erasure for profile '{profile}': {status_str}")
446
459
  for k, v in counts.items():
447
460
  print(f" {k}: {v}")
@@ -449,7 +462,7 @@ def _cmd_gdpr_erase(args: Namespace) -> None:
449
462
  print(" Backups/ contain outstanding obligation — see C1 gap.")
450
463
  print(" Verify receipts: slm gdpr verify --profile", profile)
451
464
 
452
- if not complete:
465
+ if not complete or not provable:
453
466
  sys.exit(1)
454
467
 
455
468
 
@@ -24,7 +24,10 @@ _os.environ.setdefault('TORCH_DEVICE', 'cpu')
24
24
  import argparse
25
25
  import sys
26
26
 
27
- from superlocalmemory.core.config import CANONICAL_RECALL_LIMIT
27
+ from superlocalmemory.core.config import (
28
+ CANONICAL_LIST_LIMIT,
29
+ CANONICAL_RECALL_LIMIT,
30
+ )
28
31
 
29
32
  _HELP_EPILOG = """\
30
33
  operating modes:
@@ -344,6 +347,19 @@ def main() -> None:
344
347
  db_scale_p.add_argument("--stage-id", help="Stage identifier required by verify/promote")
345
348
  db_scale_p.add_argument("--backup-id", help="Backup identifier required by rollback")
346
349
 
350
+ db_regraph_p = db_sub.add_parser(
351
+ "regraph",
352
+ help="Re-derive the graph copy of your memories from the store",
353
+ )
354
+ db_regraph_p.add_argument(
355
+ "--check", action="store_true",
356
+ help="Report how far the graph copy has drifted; change nothing",
357
+ )
358
+ db_regraph_p.add_argument(
359
+ "--profile", default="",
360
+ help="Workspace to re-derive. Default: all of them",
361
+ )
362
+
347
363
  db_reembed_p = db_sub.add_parser(
348
364
  "reembed",
349
365
  help="Backfill NULL embeddings (facts never embedded)",
@@ -503,7 +519,8 @@ def main() -> None:
503
519
 
504
520
  list_p = sub.add_parser("list", help="List recent memories chronologically (shows IDs for delete/update)")
505
521
  list_p.add_argument(
506
- "--limit", "-n", type=int, default=20, help="Number of entries (default 20)",
522
+ "--limit", "-n", type=int, default=CANONICAL_LIST_LIMIT,
523
+ help=f"Number of entries (default {CANONICAL_LIST_LIMIT})",
507
524
  )
508
525
  list_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
509
526
 
@@ -530,6 +547,11 @@ def main() -> None:
530
547
  "--quick", action="store_true",
531
548
  help="Run only the fast checks (deps + config); skip daemon/embedding probes",
532
549
  )
550
+ doctor_p.add_argument(
551
+ "--deep", action="store_true",
552
+ help="Read every database page (PRAGMA integrity_check) instead of the "
553
+ "structural check; slow on a large store",
554
+ )
533
555
  doctor_p.add_argument(
534
556
  "--fix", action="store_true",
535
557
  help="Auto-repair fixable components (re-download missing models, "
@@ -37,6 +37,49 @@ _MAX_RETRIES = 5
37
37
  _RETRY_BASE_SECONDS = 0.1
38
38
 
39
39
 
40
+ def _load_vector_extension(conn: sqlite3.Connection) -> bool:
41
+ """Make vector search available on this connection. Returns whether it loaded.
42
+
43
+ Without this the vector table cannot be created, so every semantic lookup
44
+ over the code graph returned nothing — not an error, just an empty result,
45
+ with one line in the maintenance log saying embeddings were disabled. The
46
+ extension was installed and working the whole time; no connection ever asked
47
+ for it.
48
+
49
+ Loaded per connection because that is the only scope SQLite offers: an
50
+ extension is bound to a connection, not to a database file, and this class
51
+ opens a fresh connection per statement.
52
+
53
+ The import stays inside the function. At module level it would make the
54
+ whole code graph unimportable wherever the wheel is unavailable, which is a
55
+ platform detail and not a reason to lose the rest of the feature.
56
+ """
57
+ try:
58
+ import sqlite_vec
59
+ except Exception as exc: # ImportError, or a broken native build
60
+ logger.debug("vector search unavailable: %s", exc)
61
+ return False
62
+ try:
63
+ conn.enable_load_extension(True)
64
+ except AttributeError as exc:
65
+ # Python built against a SQLite without extension support.
66
+ logger.debug("this SQLite cannot load extensions: %s", exc)
67
+ return False
68
+ try:
69
+ sqlite_vec.load(conn)
70
+ return True
71
+ except Exception as exc:
72
+ logger.debug("vector extension failed to load: %s", exc)
73
+ return False
74
+ finally:
75
+ # Closed again either way. Leaving extension loading enabled on a
76
+ # connection widens what any later SQL on it is allowed to do.
77
+ try:
78
+ conn.enable_load_extension(False)
79
+ except Exception: # pragma: no cover — defensive
80
+ pass
81
+
82
+
40
83
  class CodeGraphDatabase:
41
84
  """SQLite database manager for code_graph.db.
42
85
 
@@ -70,6 +113,7 @@ class CodeGraphDatabase:
70
113
  conn.execute("PRAGMA journal_mode=WAL")
71
114
  conn.execute("PRAGMA foreign_keys=ON")
72
115
  conn.execute("PRAGMA synchronous=NORMAL")
116
+ _load_vector_extension(conn)
73
117
  return conn
74
118
 
75
119
  def execute(