superlocalmemory 4.0.9 → 4.0.10
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/CHANGELOG.md +75 -0
- package/README.md +3 -3
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +1 -1
- 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 +1 -1
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/SKILL.md +1 -1
- package/plugin/skills/slm-recall/SKILL.md +1 -1
- package/plugin/skills/slm-remember/SKILL.md +1 -1
- package/plugin/skills/slm-scope/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/pyproject.toml +1 -1
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/cli/commands.py +45 -2
- package/src/superlocalmemory/cli/main.py +2 -2
- package/src/superlocalmemory/code_graph/bridge/maintenance.py +8 -0
- package/src/superlocalmemory/core/fact_consolidator.py +316 -125
- package/src/superlocalmemory/core/maintenance.py +44 -6
- package/src/superlocalmemory/core/memory_health.py +266 -0
- package/src/superlocalmemory/core/operation_policy_registry.py +1 -1
- package/src/superlocalmemory/core/operation_request.py +1 -1
- package/src/superlocalmemory/core/ops_remediation.py +2 -2
- package/src/superlocalmemory/core/store_pipeline.py +78 -3
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +15 -1
- package/src/superlocalmemory/mcp/server.py +1 -1
- package/src/superlocalmemory/mcp/session_binding.py +92 -0
- package/src/superlocalmemory/mcp/tools_core.py +40 -39
- package/src/superlocalmemory/mcp/tools_ops.py +2 -2
- package/src/superlocalmemory/retrieval/bm25_channel.py +4 -8
- package/src/superlocalmemory/retrieval/entity_channel.py +7 -1
- package/src/superlocalmemory/retrieval/scope_policy.py +22 -1
- package/src/superlocalmemory/retrieval/temporal_channel.py +13 -1
- package/src/superlocalmemory/retrieval/vector_store.py +63 -0
- package/src/superlocalmemory/server/api.py +6 -1
- package/src/superlocalmemory/server/asset_versions.py +171 -0
- package/src/superlocalmemory/server/routes/abstraction.py +201 -0
- package/src/superlocalmemory/server/routes/data_io.py +29 -1
- package/src/superlocalmemory/server/routes/entity.py +13 -1
- package/src/superlocalmemory/server/routes/mesh.py +1 -1
- package/src/superlocalmemory/server/routes/v3_api.py +2 -2
- package/src/superlocalmemory/server/ui.py +8 -1
- package/src/superlocalmemory/server/unified_daemon.py +111 -9
- package/src/superlocalmemory/storage/_migration_internals.py +4 -0
- package/src/superlocalmemory/storage/database.py +128 -30
- package/src/superlocalmemory/storage/migration_runner.py +11 -0
- package/src/superlocalmemory/storage/migrations/M043_quarantine_display_summaries.py +488 -0
- package/src/superlocalmemory/storage/schema.py +98 -0
- package/src/superlocalmemory/summaries/base.py +1 -1
- package/src/superlocalmemory/summaries/non_answer.py +223 -0
- package/src/superlocalmemory/ui/index.html +1 -1
- package/src/superlocalmemory/ui/js/od-memories.js +190 -1
- package/src/superlocalmemory/ui/js/od-ops-health.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,81 @@ All notable changes to SuperLocalMemory will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [4.0.10] — Your memories, not the summarizer's
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **A background pass had been writing its own summaries into your memory, and
|
|
12
|
+
they answered your questions.** SuperLocalMemory groups related memories and
|
|
13
|
+
writes a short summary of each group, meant for the dashboard. Since June
|
|
14
|
+
those summaries were being stored as memories, where they competed with your
|
|
15
|
+
own notes — and won, because each one carried the combined subjects of
|
|
16
|
+
everything it summarised and so looked more connected than any single note you
|
|
17
|
+
had written. Asked what you were working on, a store could answer with the
|
|
18
|
+
summarizer apologising for having nothing to say. Summaries now live
|
|
19
|
+
separately and are shown on the dashboard only. They are never returned as
|
|
20
|
+
answers, by any route: recall, search, the recent list, pinned context, an
|
|
21
|
+
export, or the memory count.
|
|
22
|
+
- **Summarising a group set aside the memories in it.** That made sense while
|
|
23
|
+
the summary stood in for them in your answers. It does not now, so it has
|
|
24
|
+
stopped — and upgrading brings back the memories it had already set aside.
|
|
25
|
+
Where a store had been running long enough for those memories to have faded on
|
|
26
|
+
their own, they are restored to whatever standing their own history warrants,
|
|
27
|
+
not promoted.
|
|
28
|
+
- **Upgrading repairs an affected store by itself.** No commands, no files to
|
|
29
|
+
edit. A verified backup is taken first, the repair is safe to interrupt and
|
|
30
|
+
safe to repeat, and it reports in plain language what it changed. It also
|
|
31
|
+
keeps checking: if the problem ever reappears, the next start handles it.
|
|
32
|
+
- **The setting that turns summarising off did nothing.** It has been
|
|
33
|
+
documented and ignored since it was added.
|
|
34
|
+
- **A summary that is a refusal is no longer stored as one.** When a group has
|
|
35
|
+
nothing in common, a model does not fail — it answers in prose, and that prose
|
|
36
|
+
was indistinguishable from a summary to anything that only checked whether
|
|
37
|
+
text came back. Model output is now cleaned of chat framing and rejected if it
|
|
38
|
+
turns out to be about the request rather than about your memories. A summary
|
|
39
|
+
assembled from your own sentences is exempt, so a note that happens to be
|
|
40
|
+
phrased like a chatbot is not thrown away.
|
|
41
|
+
- **A summary of a group could pull real memories into a later grouping pass
|
|
42
|
+
and set them aside with it.**
|
|
43
|
+
- **Summarising an unchanged group repeated its work indefinitely**, including
|
|
44
|
+
calling a language model to regenerate text it already had. It now recognises
|
|
45
|
+
that nothing has changed and stops.
|
|
46
|
+
- **An exported backup carried the summaries**, and importing it would have
|
|
47
|
+
turned them back into memories on a machine where nothing was wrong.
|
|
48
|
+
- **A memory can now be dated to when it happened**, not just to when it was
|
|
49
|
+
written. Everything was previously stamped with its ingestion date, so a note
|
|
50
|
+
written today about something from March filed itself under today. A date that
|
|
51
|
+
cannot be understood is refused rather than quietly dropped.
|
|
52
|
+
- **A dated memory is now findable by its date even when nothing in it was
|
|
53
|
+
recognised as a name.** Roughly a quarter of a typical store was reachable
|
|
54
|
+
only by being recent, rather than by being about the right time.
|
|
55
|
+
- **Stored memories now record which conversation they came from.** Reading
|
|
56
|
+
memories worked this out; writing them did not, so almost nothing carried it —
|
|
57
|
+
which left the feature that spreads an answer across different conversations
|
|
58
|
+
with nothing to work with.
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
- **`slm doctor` and the dashboard now tell you whether your memories can
|
|
62
|
+
actually be found**, with the counts behind the answer: how many you have, how
|
|
63
|
+
many are searchable by meaning, and how many are being held back and why. This
|
|
64
|
+
was previously unknowable without writing your own queries against the
|
|
65
|
+
database — one machine ran for months with 44% of its memory unreachable while
|
|
66
|
+
every status line said it was healthy.
|
|
67
|
+
- **A Knowledge Overview on the Summaries tab.** What your memory knows, how
|
|
68
|
+
many memories each summary covers, and the stretch of time it spans. Summaries
|
|
69
|
+
that came back empty are counted rather than shown, and near-identical ones
|
|
70
|
+
are collapsed, so the page reflects what is there instead of padding itself.
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
- **Searching by meaning no longer spends its results on held-back summaries.**
|
|
74
|
+
On a store with a lot of them, a question close to their subject matter could
|
|
75
|
+
come back with nothing usable at all while appearing to have answered.
|
|
76
|
+
- **The startup repair no longer reports itself finished while memories remain
|
|
77
|
+
unsearchable.** It says how many are left, why, and that it will retry — and
|
|
78
|
+
it does retry, instead of recording success and never looking again.
|
|
79
|
+
- **Dashboard files now carry a version taken from their own contents**, so a
|
|
80
|
+
changed script or stylesheet is always served as a new address. The version
|
|
81
|
+
numbers were maintained by hand and had stopped matching the files they named.
|
|
82
|
+
|
|
8
83
|
## [4.0.9] — Findable the moment you write it
|
|
9
84
|
|
|
10
85
|
### Fixed
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</picture>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
|
-
<h1 align="center">SuperLocalMemory V4.0.
|
|
8
|
+
<h1 align="center">SuperLocalMemory V4.0.10</h1>
|
|
9
9
|
|
|
10
10
|
<h2 align="center">Rent the LLM. Own the memory.</h2>
|
|
11
11
|
|
|
@@ -27,12 +27,12 @@ guarantee here is stated as a falsifiable invariant, tested under an adversarial
|
|
|
27
27
|
negative control, and shipped with the harness that regenerates the evidence:
|
|
28
28
|
<code>python benchmark/run_all.py --trials 200 --output-dir results/</code>. What each experiment
|
|
29
29
|
does <em>not</em> exercise is stated too.</p>
|
|
30
|
-
<p align="center"><code>v4.0.
|
|
30
|
+
<p align="center"><code>v4.0.10</code> — one control plane: <strong>SLM-Mesh</strong> peer coordination · multi-scope memory (personal / shared / global) · profiles · Cache · Compress · 7-layer retrieval · code graph · Entity Explorer · skill evolution · Modes A/B/C · GDPR retention & audit chain · bounded loops — across CLI, MCP, dashboard, the <strong>Claude plugin</strong>, the <strong>Codex add-on</strong>, and documented IDE integrations.<br/>
|
|
31
31
|
Proxy: <code>slm wrap claude</code> · MCP: add <code>slm_compress</code> to your config · Skill: zero-config</p>
|
|
32
32
|
<p align="center"><strong>Four public arXiv preprints</strong> · V4: <a href="https://arxiv.org/abs/2608.08253">arXiv:2608.08253</a> · companion archive: <a href="https://zenodo.org/records/21853302">Zenodo 21853302</a> (<a href="https://doi.org/10.5281/zenodo.21853302">DOI 10.5281/zenodo.21853302</a>) · prior preprints: <a href="https://arxiv.org/abs/2603.02240">2603.02240</a> · <a href="https://arxiv.org/abs/2603.14588">2603.14588</a> · <a href="https://arxiv.org/abs/2604.04514">2604.04514</a>.</p>
|
|
33
33
|
|
|
34
34
|
<p align="center">
|
|
35
|
-
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/v4.0.
|
|
35
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/v4.0.10-Current_Release-2ea44f?style=for-the-badge&logo=checkmarx&logoColor=white" alt="v4.0.10 — Current Release"/></a>
|
|
36
36
|
<a href="https://arxiv.org/abs/2608.08253"><img src="https://img.shields.io/badge/arXiv-2608.08253-b31b1b?style=for-the-badge&logo=arxiv&logoColor=white" alt="SuperLocalMemory 4.0 paper on arXiv:2608.08253"/></a>
|
|
37
37
|
<a href="https://zenodo.org/records/21853302"><img src="https://img.shields.io/badge/Zenodo-10.5281%2Fzenodo.21853302-1682D4?style=for-the-badge&logo=zenodo&logoColor=white" alt="V4 paper on Zenodo: 10.5281/zenodo.21853302"/></a>
|
|
38
38
|
<a href="https://arxiv.org/abs/2603.14588"><img src="https://img.shields.io/badge/arXiv-2603.14588-b31b1b?style=for-the-badge&logo=arxiv&logoColor=white" alt="arXiv Paper"/></a>
|
package/package.json
CHANGED
package/plugin/CLAUDE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- BEGIN SuperLocalMemory v4.0.
|
|
1
|
+
<!-- BEGIN SuperLocalMemory v4.0.10 -->
|
|
2
2
|
|
|
3
3
|
## SuperLocalMemory (SLM) — Agent Rules
|
|
4
4
|
|
|
@@ -39,6 +39,6 @@ slm-recall · slm-remember · slm-session · slm-status · slm-cache · slm-comp
|
|
|
39
39
|
### Subagents
|
|
40
40
|
slm-memory-advisor (memory decisions, session hygiene, scope/profile guidance) · slm-optimize-advisor (context compression + KV cache) · slm-governance-advisor (scope/roles/compliance/GDPR)
|
|
41
41
|
|
|
42
|
-
<!-- END SuperLocalMemory v4.0.
|
|
42
|
+
<!-- END SuperLocalMemory v4.0.10 -->
|
|
43
43
|
|
|
44
|
-
SuperLocalMemory v4.0.
|
|
44
|
+
SuperLocalMemory v4.0.10 · Qualixar · AGPL-3.0-or-later
|
|
@@ -77,4 +77,4 @@ slm-scope · slm-governance · slm-profile · slm-remember · slm-recall
|
|
|
77
77
|
# What NOT to do
|
|
78
78
|
Never session_init twice; never forget without dry-run preview; never store secrets; never bypass role checks; never claim an erasure succeeded without verifying via recall.
|
|
79
79
|
|
|
80
|
-
SuperLocalMemory v4.0.
|
|
80
|
+
SuperLocalMemory v4.0.10 · Qualixar · AGPL-3.0-or-later
|
|
@@ -46,4 +46,4 @@ slm-recall · slm-remember · slm-session · slm-scope · slm-profile · slm-gov
|
|
|
46
46
|
# What NOT to do
|
|
47
47
|
Never session_init twice; never forget dry_run=False without reporting preview; never dump a whole file into remember; never invent a memory; never claim "saved" without success:true / clean CLI exit; never bypass scope or governance restrictions.
|
|
48
48
|
|
|
49
|
-
SuperLocalMemory v4.0.
|
|
49
|
+
SuperLocalMemory v4.0.10 · Qualixar · AGPL-3.0-or-later
|
|
@@ -41,4 +41,4 @@ slm-compress · slm-cache · slm-status · slm-profile
|
|
|
41
41
|
# What NOT to do
|
|
42
42
|
Never compress code-for-edit/JSON-to-parse/<500 chars; never store secrets/ccr_ids; never let optimize failure block/alter the task; never claim a specific savings %; never carry ccr_ids across profile switches.
|
|
43
43
|
|
|
44
|
-
SuperLocalMemory v4.0.
|
|
44
|
+
SuperLocalMemory v4.0.10 · Qualixar · AGPL-3.0-or-later
|
package/plugin/requirements.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
superlocalmemory==4.0.
|
|
1
|
+
superlocalmemory==4.0.10
|
|
@@ -129,4 +129,4 @@ When the SLM MCP server is unavailable, use these CLI equivalents:
|
|
|
129
129
|
- **slm-optimize-advisor** — context compression and KV cache
|
|
130
130
|
- **slm-governance-advisor** — scope/role compliance, retention policies, GDPR
|
|
131
131
|
|
|
132
|
-
SuperLocalMemory v4.0.
|
|
132
|
+
SuperLocalMemory v4.0.10 · Qualixar · AGPL-3.0-or-later
|
package/pyproject.toml
CHANGED
|
@@ -32,7 +32,7 @@ if "OMP_NUM_THREADS" not in os.environ:
|
|
|
32
32
|
os.environ["OMP_NUM_THREADS"] = "2"
|
|
33
33
|
# ---------------------------------------------------------------------------
|
|
34
34
|
|
|
35
|
-
__version__ = "4.0.
|
|
35
|
+
__version__ = "4.0.10"
|
|
36
36
|
|
|
37
37
|
_REQUIRED_VERSIONS = {
|
|
38
38
|
"sentence_transformers": "5.3.0",
|
|
@@ -271,7 +271,7 @@ def _cmd_loop(args: Namespace) -> None:
|
|
|
271
271
|
|
|
272
272
|
|
|
273
273
|
def _cmd_ops(args: Namespace) -> None:
|
|
274
|
-
"""
|
|
274
|
+
"""Operational recovery & admin remediation commands."""
|
|
275
275
|
from superlocalmemory.cli.ops_cmd import cmd_ops
|
|
276
276
|
cmd_ops(args)
|
|
277
277
|
|
|
@@ -416,7 +416,7 @@ def dispatch(args: Namespace) -> None:
|
|
|
416
416
|
"loop": _cmd_loop,
|
|
417
417
|
# V3.8.2 super-help — grouped overview of every command + topics
|
|
418
418
|
"help": cmd_help,
|
|
419
|
-
#
|
|
419
|
+
# Operational recovery & admin remediation
|
|
420
420
|
"ops": _cmd_ops,
|
|
421
421
|
# V4.0.6: GDPR subject-rights CLI (Art.15/17/20)
|
|
422
422
|
"gdpr": _cmd_gdpr_dispatch,
|
|
@@ -2949,6 +2949,48 @@ def cmd_doctor(args: Namespace) -> None:
|
|
|
2949
2949
|
f"enabled [{_surface_str}] {_stats}",
|
|
2950
2950
|
)
|
|
2951
2951
|
|
|
2952
|
+
# Memory answer-ability.
|
|
2953
|
+
#
|
|
2954
|
+
# Every other check here asks whether a component is installed. None of
|
|
2955
|
+
# them asked the only question that matters to the owner: can my memories
|
|
2956
|
+
# actually be found? One machine ran for months with 43.7% of its store
|
|
2957
|
+
# unreachable while doctor reported everything green, because the reachable
|
|
2958
|
+
# share was never counted.
|
|
2959
|
+
memory_health_data: dict | None = None
|
|
2960
|
+
try:
|
|
2961
|
+
from superlocalmemory.core.config import SLMConfig as _HealthCfg
|
|
2962
|
+
from superlocalmemory.core.memory_health import describe, measure
|
|
2963
|
+
_h = measure(_HealthCfg.load().db_path)
|
|
2964
|
+
memory_health_data = {
|
|
2965
|
+
"live_facts": _h.live_facts,
|
|
2966
|
+
"findable_by_meaning": _h.findable_by_meaning,
|
|
2967
|
+
"missing_vector": _h.missing_vector,
|
|
2968
|
+
"withheld_summaries": _h.withheld_summaries,
|
|
2969
|
+
"display_summaries": _h.display_summaries,
|
|
2970
|
+
"hidden_by_forgetting": _h.hidden_by_forgetting,
|
|
2971
|
+
"inconsistently_hidden": _h.inconsistently_hidden,
|
|
2972
|
+
"reachability": round(_h.reachability, 4),
|
|
2973
|
+
"healthy": _h.healthy,
|
|
2974
|
+
"unavailable": list(_h.unavailable),
|
|
2975
|
+
"summary": describe(_h),
|
|
2976
|
+
}
|
|
2977
|
+
_detail = " ".join(describe(_h))
|
|
2978
|
+
if _h.healthy:
|
|
2979
|
+
_check("Memory answer-ability", "PASS", _detail)
|
|
2980
|
+
elif _h.inconsistently_hidden or _h.reachability < 0.9:
|
|
2981
|
+
_check(
|
|
2982
|
+
"Memory answer-ability", "FAIL", _detail,
|
|
2983
|
+
fix="slm restart",
|
|
2984
|
+
)
|
|
2985
|
+
else:
|
|
2986
|
+
_check("Memory answer-ability", "WARN", _detail,
|
|
2987
|
+
fix="slm db reembed --missing-only")
|
|
2988
|
+
except Exception as _mh_exc: # noqa: BLE001 — a report must not break doctor
|
|
2989
|
+
_check(
|
|
2990
|
+
"Memory answer-ability", "WARN",
|
|
2991
|
+
f"could not be measured: {_mh_exc}",
|
|
2992
|
+
)
|
|
2993
|
+
|
|
2952
2994
|
# Summary
|
|
2953
2995
|
if use_json:
|
|
2954
2996
|
from superlocalmemory.cli.json_output import json_print
|
|
@@ -2959,6 +3001,7 @@ def cmd_doctor(args: Namespace) -> None:
|
|
|
2959
3001
|
json_print("doctor", data={
|
|
2960
3002
|
"checks": checks,
|
|
2961
3003
|
"summary": {"passed": passed, "warned": warned, "failed": failed},
|
|
3004
|
+
"memory_health": memory_health_data,
|
|
2962
3005
|
}, next_actions=next_actions)
|
|
2963
3006
|
else:
|
|
2964
3007
|
print(f"\nSummary: {passed} passed, {warned} warnings, {failed} failed")
|
|
@@ -977,7 +977,7 @@ def main() -> None:
|
|
|
977
977
|
|
|
978
978
|
register_summary_parser(sub)
|
|
979
979
|
|
|
980
|
-
#
|
|
980
|
+
# V4.0.6: GDPR subject-rights CLI (Art.15/17/20)
|
|
981
981
|
gdpr_p = sub.add_parser(
|
|
982
982
|
"gdpr",
|
|
983
983
|
help="GDPR subject rights: status, export (Art.15/20), erase (Art.17), verify",
|
|
@@ -1051,7 +1051,7 @@ def main() -> None:
|
|
|
1051
1051
|
"--json", action="store_true", help="Output structured JSON",
|
|
1052
1052
|
)
|
|
1053
1053
|
|
|
1054
|
-
#
|
|
1054
|
+
# Operational recovery & admin remediation
|
|
1055
1055
|
ops_p = sub.add_parser(
|
|
1056
1056
|
"ops",
|
|
1057
1057
|
help="Operational recovery: list failures, resolve stuck ops, check status",
|
|
@@ -103,6 +103,14 @@ def _fact_rows(
|
|
|
103
103
|
# the pass linked happily in tests and would have linked NOTHING for any
|
|
104
104
|
# actual user — 3,608 of 3,608 facts filtered out on this machine.
|
|
105
105
|
sql += "AND COALESCE(archive_status, 'live') != 'archived' "
|
|
106
|
+
# Same reasoning for withheld rows: a model's non-answer has no code
|
|
107
|
+
# entities worth resolving, and a link from one would surface it in the
|
|
108
|
+
# bridge's enrichment text.
|
|
109
|
+
try:
|
|
110
|
+
if memory_db._has_quarantine_column():
|
|
111
|
+
sql += "AND COALESCE(quarantined, 0) = 0 "
|
|
112
|
+
except Exception: # pragma: no cover - helper absent on an unusual manager
|
|
113
|
+
pass
|
|
106
114
|
|
|
107
115
|
params: list[Any] = [profile_id]
|
|
108
116
|
if since:
|