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.
- package/.claude-plugin/marketplace.json +12 -2
- package/CHANGELOG.md +244 -0
- package/README.md +40 -75
- package/package.json +6 -3
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +4 -4
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/agents/slm-optimize-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-governance/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-loop/SKILL.md +2 -2
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/SKILL.md +5 -5
- package/plugin/skills/slm-recall/SKILL.md +102 -15
- package/plugin/skills/slm-remember/SKILL.md +35 -3
- package/plugin/skills/slm-scope/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +29 -3
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/rules/AGENTS.md +16 -8
- package/plugin-src/skills/slm-cache/SKILL.md +1 -1
- package/plugin-src/skills/slm-compress/SKILL.md +1 -1
- package/plugin-src/skills/slm-governance/SKILL.md +1 -1
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-loop/SKILL.md +2 -2
- package/plugin-src/skills/slm-mesh/SKILL.md +1 -1
- package/plugin-src/skills/slm-profile/SKILL.md +5 -5
- package/plugin-src/skills/slm-recall/SKILL.md +102 -15
- package/plugin-src/skills/slm-remember/SKILL.md +35 -3
- package/plugin-src/skills/slm-scope/SKILL.md +1 -1
- package/plugin-src/skills/slm-session/SKILL.md +29 -3
- package/plugin-src/skills/slm-status/SKILL.md +1 -1
- package/pyproject.toml +1 -1
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/cli/commands.py +357 -18
- package/src/superlocalmemory/cli/daemon.py +30 -0
- package/src/superlocalmemory/cli/db_migrate.py +71 -1
- package/src/superlocalmemory/cli/gdpr_cmd.py +15 -2
- package/src/superlocalmemory/cli/main.py +24 -2
- package/src/superlocalmemory/code_graph/database.py +44 -0
- package/src/superlocalmemory/compliance/gdpr.py +449 -39
- package/src/superlocalmemory/core/admission.py +231 -11
- package/src/superlocalmemory/core/backend_orchestrator.py +190 -84
- package/src/superlocalmemory/core/config.py +90 -11
- package/src/superlocalmemory/core/consolidation_engine.py +34 -0
- package/src/superlocalmemory/core/engine.py +140 -11
- package/src/superlocalmemory/core/graph_analyzer.py +76 -112
- package/src/superlocalmemory/core/graph_metrics.py +597 -0
- package/src/superlocalmemory/core/graph_pruner.py +121 -0
- package/src/superlocalmemory/core/maintenance_scheduler.py +205 -0
- package/src/superlocalmemory/core/mode_capability.py +111 -0
- package/src/superlocalmemory/core/ollama_validator.py +315 -0
- package/src/superlocalmemory/core/projection_drain.py +380 -0
- package/src/superlocalmemory/core/recall_pipeline.py +390 -3
- package/src/superlocalmemory/core/recall_worker.py +6 -3
- package/src/superlocalmemory/core/scale_autopromote.py +196 -0
- package/src/superlocalmemory/core/scale_engine.py +16 -2
- package/src/superlocalmemory/core/score_contract.py +21 -1
- package/src/superlocalmemory/core/session_identity.py +85 -0
- package/src/superlocalmemory/core/status_contract.py +108 -0
- package/src/superlocalmemory/core/worker_pool.py +4 -4
- package/src/superlocalmemory/core/working_memory.py +288 -0
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +36 -6
- package/src/superlocalmemory/encoding/context_generator.py +1 -1
- package/src/superlocalmemory/encoding/entity_resolver.py +38 -0
- package/src/superlocalmemory/encoding/fact_extractor.py +18 -14
- package/src/superlocalmemory/encoding/prospective_markers.py +262 -0
- package/src/superlocalmemory/encoding/type_router.py +12 -12
- package/src/superlocalmemory/evolution/mutation_generator.py +30 -4
- package/src/superlocalmemory/graph/cozo_adjacency.py +122 -0
- package/src/superlocalmemory/graph/cozo_backend.py +103 -138
- package/src/superlocalmemory/hooks/portable_kit.py +10 -2
- package/src/superlocalmemory/learning/bandit.py +43 -0
- package/src/superlocalmemory/learning/consolidation_worker.py +54 -0
- package/src/superlocalmemory/learning/database.py +60 -3
- package/src/superlocalmemory/learning/entity_compiler.py +21 -58
- package/src/superlocalmemory/learning/feedback.py +3 -1
- package/src/superlocalmemory/learning/outcomes.py +47 -16
- package/src/superlocalmemory/learning/pattern_miner.py +28 -3
- package/src/superlocalmemory/learning/pattern_miner_constants.py +43 -0
- package/src/superlocalmemory/learning/pcos.py +291 -0
- package/src/superlocalmemory/learning/reward_from_outcomes.py +365 -0
- package/src/superlocalmemory/learning/reward_proxy.py +100 -10
- package/src/superlocalmemory/learning/signal_kinds.py +79 -0
- package/src/superlocalmemory/mcp/profiles.py +14 -2
- package/src/superlocalmemory/mcp/tools_active.py +2 -1
- package/src/superlocalmemory/mcp/tools_core.py +31 -3
- package/src/superlocalmemory/mcp/tools_v28.py +20 -1
- package/src/superlocalmemory/parameterization/pattern_extractor.py +14 -1
- package/src/superlocalmemory/parameterization/soft_prompt_generator.py +98 -0
- package/src/superlocalmemory/retrieval/bm25_channel.py +64 -3
- package/src/superlocalmemory/retrieval/channel_status.py +117 -0
- package/src/superlocalmemory/retrieval/engine.py +106 -11
- package/src/superlocalmemory/retrieval/entity_channel.py +210 -256
- package/src/superlocalmemory/retrieval/graph_adjacency.py +219 -0
- package/src/superlocalmemory/retrieval/scope_policy.py +20 -0
- package/src/superlocalmemory/retrieval/semantic_channel.py +47 -5
- package/src/superlocalmemory/retrieval/spreading.py +288 -0
- package/src/superlocalmemory/server/api.py +24 -5
- package/src/superlocalmemory/server/bandit_loops.py +17 -1
- package/src/superlocalmemory/server/rbac_enforce.py +26 -6
- package/src/superlocalmemory/server/recall_health.py +87 -10
- package/src/superlocalmemory/server/recall_serializer.py +9 -0
- package/src/superlocalmemory/server/routes/behavioral.py +75 -10
- package/src/superlocalmemory/server/routes/compliance.py +98 -18
- package/src/superlocalmemory/server/routes/config_api.py +186 -4
- package/src/superlocalmemory/server/routes/evolution.py +178 -0
- package/src/superlocalmemory/server/routes/ingest.py +8 -0
- package/src/superlocalmemory/server/routes/learning_telemetry.py +2 -1
- package/src/superlocalmemory/server/routes/memories.py +49 -7
- package/src/superlocalmemory/server/routes/timeline.py +4 -0
- package/src/superlocalmemory/server/routes/v3_api.py +191 -15
- package/src/superlocalmemory/server/ui.py +20 -4
- package/src/superlocalmemory/server/unified_daemon.py +241 -7
- package/src/superlocalmemory/storage/_migration_internals.py +54 -2
- package/src/superlocalmemory/storage/_schema_version.py +24 -3
- package/src/superlocalmemory/storage/database.py +477 -59
- package/src/superlocalmemory/storage/embedding_codec.py +71 -0
- package/src/superlocalmemory/storage/lineage_retention.py +236 -0
- package/src/superlocalmemory/storage/logical_edges.py +43 -2
- package/src/superlocalmemory/storage/migration_runner.py +119 -0
- package/src/superlocalmemory/storage/migrations/M043_quarantine_display_summaries.py +60 -36
- package/src/superlocalmemory/storage/migrations/M044_play_carries_its_own_evidence.py +127 -0
- package/src/superlocalmemory/storage/migrations/M045_fact_outcome_score.py +158 -0
- package/src/superlocalmemory/storage/migrations/M046_prospective_memory_has_its_own_name.py +620 -0
- package/src/superlocalmemory/storage/migrations/M047_fisher_vectors_are_stored_like_every_other_vector.py +306 -0
- package/src/superlocalmemory/storage/migrations/M048_upcoming_holds_only_what_is_upcoming.py +207 -0
- package/src/superlocalmemory/storage/migrations/M049_a_schema_version_marker_is_one_row.py +201 -0
- package/src/superlocalmemory/storage/migrations.py +18 -2
- package/src/superlocalmemory/storage/models.py +40 -1
- package/src/superlocalmemory/storage/projection_outbox.py +346 -0
- package/src/superlocalmemory/storage/retention_policy.py +860 -0
- package/src/superlocalmemory/storage/schema.py +35 -1
- package/src/superlocalmemory/storage/write_coordinator.py +19 -2
- package/src/superlocalmemory/trust/scorer.py +43 -1
- package/src/superlocalmemory/ui/index.html +9 -18
- package/src/superlocalmemory/ui/js/event-delegation.js +12 -1
- package/src/superlocalmemory/ui/js/od-health.js +28 -6
- package/src/superlocalmemory/ui/js/od-memories.js +19 -0
- package/src/superlocalmemory/ui/js/od-settings.js +87 -1
- package/src/superlocalmemory/ui/js/recall-lab.js +78 -3
|
@@ -156,6 +156,16 @@ from superlocalmemory.storage.migrations import (
|
|
|
156
156
|
from superlocalmemory.storage.migrations import (
|
|
157
157
|
M043_quarantine_display_summaries as _M043,
|
|
158
158
|
)
|
|
159
|
+
from superlocalmemory.storage.migrations import (
|
|
160
|
+
M044_play_carries_its_own_evidence as _M044,
|
|
161
|
+
)
|
|
162
|
+
from superlocalmemory.storage.migrations import (
|
|
163
|
+
M045_fact_outcome_score as _M045,
|
|
164
|
+
M046_prospective_memory_has_its_own_name as _M046,
|
|
165
|
+
M047_fisher_vectors_are_stored_like_every_other_vector as _M047,
|
|
166
|
+
M048_upcoming_holds_only_what_is_upcoming as _M048,
|
|
167
|
+
M049_a_schema_version_marker_is_one_row as _M049,
|
|
168
|
+
)
|
|
159
169
|
|
|
160
170
|
# Emit under the runner's logger name so operational log filters that key on
|
|
161
171
|
# "superlocalmemory.storage.migration_runner" keep matching after this split.
|
|
@@ -207,6 +217,12 @@ _MODULES = {
|
|
|
207
217
|
_M041.NAME: _M041,
|
|
208
218
|
_M042.NAME: _M042,
|
|
209
219
|
_M043.NAME: _M043,
|
|
220
|
+
_M044.NAME: _M044,
|
|
221
|
+
_M045.NAME: _M045,
|
|
222
|
+
_M046.NAME: _M046,
|
|
223
|
+
_M047.NAME: _M047,
|
|
224
|
+
_M048.NAME: _M048,
|
|
225
|
+
_M049.NAME: _M049,
|
|
210
226
|
}
|
|
211
227
|
|
|
212
228
|
# Exact historical DDL fingerprints whose resulting schema is intentionally
|
|
@@ -245,9 +261,24 @@ def _ddl_hash(ddl: str) -> str:
|
|
|
245
261
|
return hashlib.sha256(ddl.encode("utf-8")).hexdigest()
|
|
246
262
|
|
|
247
263
|
|
|
264
|
+
#: How long a migration waits for a database another process is holding.
|
|
265
|
+
#:
|
|
266
|
+
#: Without this, SQLite raises SQLITE_BUSY the instant a write lock is taken,
|
|
267
|
+
#: and a migration that runs while the daemon happens to be writing is recorded
|
|
268
|
+
#: as failed rather than retried. A migration that rebuilds a table takes an
|
|
269
|
+
#: exclusive lock, so it is exactly the one most likely to collide — and its
|
|
270
|
+
#: failure leaves an upgrade wedged until someone notices.
|
|
271
|
+
#:
|
|
272
|
+
#: Fifteen seconds is longer than any single write this codebase performs and
|
|
273
|
+
#: short enough that a genuinely stuck lock still surfaces as a failure rather
|
|
274
|
+
#: than a hang.
|
|
275
|
+
_MIGRATION_BUSY_TIMEOUT_MS = 15_000
|
|
276
|
+
|
|
277
|
+
|
|
248
278
|
def _connect(db_path: Path) -> sqlite3.Connection:
|
|
249
279
|
# isolation_level=None → we manage transactions explicitly via DDL.
|
|
250
280
|
conn = sqlite3.connect(db_path, isolation_level=None)
|
|
281
|
+
conn.execute(f"PRAGMA busy_timeout = {_MIGRATION_BUSY_TIMEOUT_MS};")
|
|
251
282
|
conn.execute("PRAGMA foreign_keys = OFF;")
|
|
252
283
|
return conn
|
|
253
284
|
|
|
@@ -301,6 +332,22 @@ def _delete_log(conn: sqlite3.Connection, name: str) -> None:
|
|
|
301
332
|
conn.execute("DELETE FROM migration_log WHERE name = ?", (name,))
|
|
302
333
|
|
|
303
334
|
|
|
335
|
+
def _why_unmet(mod, conn) -> str:
|
|
336
|
+
"""The migration's own account of which check does not hold.
|
|
337
|
+
|
|
338
|
+
A migration may expose ``unmet(conn)`` returning a sentence. Most do not,
|
|
339
|
+
and for those the caller keeps its generic wording. Never raises: this runs
|
|
340
|
+
while reporting a failure and must not become a second one.
|
|
341
|
+
"""
|
|
342
|
+
fn = getattr(mod, "unmet", None)
|
|
343
|
+
if not callable(fn):
|
|
344
|
+
return ""
|
|
345
|
+
try:
|
|
346
|
+
return str(fn(conn) or "")
|
|
347
|
+
except Exception: # noqa: BLE001 - a detail string is not worth a crash
|
|
348
|
+
return ""
|
|
349
|
+
|
|
350
|
+
|
|
304
351
|
def _apply_single(
|
|
305
352
|
conn: sqlite3.Connection,
|
|
306
353
|
migration: Migration,
|
|
@@ -383,9 +430,12 @@ def _apply_single(
|
|
|
383
430
|
try:
|
|
384
431
|
repair_fn(conn)
|
|
385
432
|
if not bool(verify_fn(conn)):
|
|
433
|
+
_why = _why_unmet(mod, conn)
|
|
386
434
|
return (
|
|
387
435
|
"failed",
|
|
388
|
-
f"safe repair did not restore
|
|
436
|
+
f"safe repair did not restore "
|
|
437
|
+
f"{migration.name}"
|
|
438
|
+
+ (f": {_why}" if _why else ""),
|
|
389
439
|
)
|
|
390
440
|
_upsert_log(conn, migration.name, ddl_hash, "complete")
|
|
391
441
|
return (
|
|
@@ -451,9 +501,11 @@ def _apply_single(
|
|
|
451
501
|
)
|
|
452
502
|
try:
|
|
453
503
|
if not bool(verify_fn(conn)):
|
|
504
|
+
_why = _why_unmet(mod, conn)
|
|
454
505
|
return (
|
|
455
506
|
"failed",
|
|
456
|
-
f"safe repair did not restore {migration.name}"
|
|
507
|
+
f"safe repair did not restore {migration.name}"
|
|
508
|
+
+ (f": {_why}" if _why else ""),
|
|
457
509
|
)
|
|
458
510
|
except sqlite3.Error as exc:
|
|
459
511
|
return (
|
|
@@ -20,10 +20,31 @@ from __future__ import annotations
|
|
|
20
20
|
import sqlite3
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
|
|
23
|
-
#: Highest schema_version this runner can write. Matches the trailing serial
|
|
24
|
-
#:
|
|
23
|
+
#: Highest schema_version this runner can write. Matches the trailing serial of
|
|
24
|
+
#: the latest migration (M049). Increment when adding new migrations or
|
|
25
25
|
#: table-level breaking changes.
|
|
26
|
-
|
|
26
|
+
#:
|
|
27
|
+
#: This sat at 42 while M043, M044 and M045 shipped, so for three migrations the
|
|
28
|
+
#: ceiling did not move and nothing prevented an older build from opening a
|
|
29
|
+
#: newer store. That was tolerable only because those three were additive: a
|
|
30
|
+
#: build that did not know about a new column or table simply never read it.
|
|
31
|
+
#:
|
|
32
|
+
#: M046 is not additive. It rebuilds ``atomic_facts`` with a constraint that
|
|
33
|
+
#: rejects the value an older build classifies planned events as, so an older
|
|
34
|
+
#: writer against a migrated store fails its INSERT. The ceiling is what turns
|
|
35
|
+
#: that from a lost memory into a refusal to start, which is why it moves here
|
|
36
|
+
#: and why it moves to the trailing serial rather than to 43.
|
|
37
|
+
#:
|
|
38
|
+
#: M049 is additive — a unique index on ``schema_version`` plus the removal of
|
|
39
|
+
#: the duplicate rows that index could not otherwise be created over — so an
|
|
40
|
+
#: older build could in principle read a store it has touched. The ceiling
|
|
41
|
+
#: still moves, because the convention is "trailing serial, always": the cost of
|
|
42
|
+
#: moving it for an additive migration is an older build declining a store it
|
|
43
|
+
#: could have read, and the cost of NOT moving it for one that turns out not to
|
|
44
|
+
#: be additive is a silent bad write. Those are not comparable, and judging
|
|
45
|
+
#: additivity per migration is exactly the judgement that let it fall three
|
|
46
|
+
#: behind.
|
|
47
|
+
SUPPORTED_SCHEMA_VERSION: int = 49
|
|
27
48
|
|
|
28
49
|
|
|
29
50
|
class SchemaVersionError(RuntimeError):
|