superlocalmemory 4.1.22 → 4.1.23

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 (172) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +99 -0
  3. package/README.md +50 -27
  4. package/antigravity-plugin/_GENERATED.md +33 -0
  5. package/antigravity-plugin/agents/slm-governance-advisor.md +78 -0
  6. package/antigravity-plugin/agents/slm-loop-runner.md +82 -0
  7. package/antigravity-plugin/agents/slm-memory-advisor.md +50 -0
  8. package/antigravity-plugin/agents/slm-optimize-advisor.md +44 -0
  9. package/antigravity-plugin/commands/slm-loop.md +33 -0
  10. package/antigravity-plugin/hooks/hooks.json +59 -0
  11. package/antigravity-plugin/hooks.json +42 -0
  12. package/antigravity-plugin/mcp_config.json +14 -0
  13. package/antigravity-plugin/plugin.json +25 -0
  14. package/antigravity-plugin/scripts/antigravity_hook_adapter.py +85 -0
  15. package/antigravity-plugin/skills/slm-bot-memory/SKILL.md +146 -0
  16. package/antigravity-plugin/skills/slm-cache/SKILL.md +147 -0
  17. package/antigravity-plugin/skills/slm-compress/SKILL.md +150 -0
  18. package/antigravity-plugin/skills/slm-getting-started-bot/SKILL.md +146 -0
  19. package/antigravity-plugin/skills/slm-governance/SKILL.md +221 -0
  20. package/antigravity-plugin/skills/slm-graph/SKILL.md +327 -0
  21. package/antigravity-plugin/skills/slm-loop/SKILL.md +153 -0
  22. package/antigravity-plugin/skills/slm-mesh/SKILL.md +287 -0
  23. package/antigravity-plugin/skills/slm-profile/SKILL.md +159 -0
  24. package/antigravity-plugin/skills/slm-recall/SKILL.md +430 -0
  25. package/antigravity-plugin/skills/slm-remember/SKILL.md +370 -0
  26. package/antigravity-plugin/skills/slm-scope/SKILL.md +183 -0
  27. package/antigravity-plugin/skills/slm-session/SKILL.md +291 -0
  28. package/antigravity-plugin/skills/slm-status/SKILL.md +185 -0
  29. package/antigravity-plugin/skills/slm-web-access/SKILL.md +91 -0
  30. package/codex-plugin/.claude-plugin/plugin.json +19 -0
  31. package/codex-plugin/.codex/config.toml +40 -0
  32. package/codex-plugin/.codex-plugin/plugin.json +43 -0
  33. package/codex-plugin/.mcp.json +16 -0
  34. package/codex-plugin/AGENTS.md +161 -0
  35. package/codex-plugin/README.md +205 -0
  36. package/codex-plugin/_GENERATED.md +52 -0
  37. package/codex-plugin/agents/slm-governance-advisor.md +78 -0
  38. package/codex-plugin/agents/slm-loop-runner.md +82 -0
  39. package/codex-plugin/agents/slm-memory-advisor.md +50 -0
  40. package/codex-plugin/agents/slm-optimize-advisor.md +44 -0
  41. package/codex-plugin/commands/slm-loop.md +33 -0
  42. package/codex-plugin/hooks/hooks.json +59 -0
  43. package/codex-plugin/scripts/ensure-venv.bat +108 -0
  44. package/codex-plugin/scripts/ensure-venv.sh +100 -0
  45. package/codex-plugin/scripts/slm-launch +55 -0
  46. package/codex-plugin/scripts/slm-launch.bat +30 -0
  47. package/codex-plugin/skills/slm-bot-memory/SKILL.md +146 -0
  48. package/codex-plugin/skills/slm-cache/SKILL.md +147 -0
  49. package/codex-plugin/skills/slm-compress/SKILL.md +150 -0
  50. package/codex-plugin/skills/slm-getting-started-bot/SKILL.md +146 -0
  51. package/codex-plugin/skills/slm-governance/SKILL.md +221 -0
  52. package/codex-plugin/skills/slm-graph/SKILL.md +327 -0
  53. package/codex-plugin/skills/slm-loop/SKILL.md +153 -0
  54. package/codex-plugin/skills/slm-mesh/SKILL.md +287 -0
  55. package/codex-plugin/skills/slm-profile/SKILL.md +159 -0
  56. package/codex-plugin/skills/slm-recall/SKILL.md +430 -0
  57. package/codex-plugin/skills/slm-remember/SKILL.md +370 -0
  58. package/codex-plugin/skills/slm-scope/SKILL.md +183 -0
  59. package/codex-plugin/skills/slm-session/SKILL.md +291 -0
  60. package/codex-plugin/skills/slm-status/SKILL.md +185 -0
  61. package/codex-plugin/skills/slm-web-access/SKILL.md +91 -0
  62. package/copilot-plugin/.github/agents/slm-governance-advisor.agent.md +80 -0
  63. package/copilot-plugin/.github/agents/slm-loop-runner.agent.md +84 -0
  64. package/copilot-plugin/.github/agents/slm-memory-advisor.agent.md +52 -0
  65. package/copilot-plugin/.github/agents/slm-optimize-advisor.agent.md +46 -0
  66. package/copilot-plugin/.github/copilot-instructions.md +52 -0
  67. package/copilot-plugin/.github/hooks/slm-hooks.json +44 -0
  68. package/copilot-plugin/.github/prompts/slm-bot-memory.prompt.md +147 -0
  69. package/copilot-plugin/.github/prompts/slm-cache.prompt.md +151 -0
  70. package/copilot-plugin/.github/prompts/slm-compress.prompt.md +154 -0
  71. package/copilot-plugin/.github/prompts/slm-getting-started-bot.prompt.md +147 -0
  72. package/copilot-plugin/.github/prompts/slm-governance.prompt.md +224 -0
  73. package/copilot-plugin/.github/prompts/slm-graph.prompt.md +322 -0
  74. package/copilot-plugin/.github/prompts/slm-loop.prompt.md +159 -0
  75. package/copilot-plugin/.github/prompts/slm-mesh.prompt.md +290 -0
  76. package/copilot-plugin/.github/prompts/slm-profile.prompt.md +155 -0
  77. package/copilot-plugin/.github/prompts/slm-recall.prompt.md +434 -0
  78. package/copilot-plugin/.github/prompts/slm-remember.prompt.md +375 -0
  79. package/copilot-plugin/.github/prompts/slm-scope.prompt.md +183 -0
  80. package/copilot-plugin/.github/prompts/slm-session.prompt.md +291 -0
  81. package/copilot-plugin/.github/prompts/slm-status.prompt.md +190 -0
  82. package/copilot-plugin/.github/prompts/slm-web-access.prompt.md +95 -0
  83. package/copilot-plugin/.vscode/mcp.json +11 -0
  84. package/copilot-plugin/README.md +26 -0
  85. package/copilot-plugin/_GENERATED.md +49 -0
  86. package/copilot-plugin/scripts/ensure-venv.bat +122 -0
  87. package/copilot-plugin/scripts/ensure-venv.sh +169 -0
  88. package/copilot-plugin/scripts/slm-launch +207 -0
  89. package/copilot-plugin/scripts/slm-launch.bat +32 -0
  90. package/copilot-plugin/scripts/slm-resolve.sh +128 -0
  91. package/copilot-plugin/scripts/slm-run +76 -0
  92. package/copilot-plugin/scripts/torch-cpu-resolve.sh +86 -0
  93. package/docs/pi-dev-integration.md +0 -2
  94. package/hermes-plugin/README.md +30 -0
  95. package/hermes-plugin/_GENERATED.md +3 -0
  96. package/hermes-plugin/__init__.py +417 -0
  97. package/hermes-plugin/agents/slm-governance-advisor.md +78 -0
  98. package/hermes-plugin/agents/slm-loop-runner.md +82 -0
  99. package/hermes-plugin/agents/slm-memory-advisor.md +50 -0
  100. package/hermes-plugin/agents/slm-optimize-advisor.md +44 -0
  101. package/hermes-plugin/command-inventory.json +7 -0
  102. package/hermes-plugin/plugin.yaml +24 -0
  103. package/hermes-plugin/remote.py +390 -0
  104. package/hermes-plugin/skills/slm-bot-memory/SKILL.md +146 -0
  105. package/hermes-plugin/skills/slm-cache/SKILL.md +147 -0
  106. package/hermes-plugin/skills/slm-compress/SKILL.md +150 -0
  107. package/hermes-plugin/skills/slm-getting-started-bot/SKILL.md +146 -0
  108. package/hermes-plugin/skills/slm-governance/SKILL.md +221 -0
  109. package/hermes-plugin/skills/slm-graph/SKILL.md +327 -0
  110. package/hermes-plugin/skills/slm-loop/SKILL.md +153 -0
  111. package/hermes-plugin/skills/slm-mesh/SKILL.md +287 -0
  112. package/hermes-plugin/skills/slm-profile/SKILL.md +159 -0
  113. package/hermes-plugin/skills/slm-recall/SKILL.md +430 -0
  114. package/hermes-plugin/skills/slm-remember/SKILL.md +370 -0
  115. package/hermes-plugin/skills/slm-scope/SKILL.md +183 -0
  116. package/hermes-plugin/skills/slm-session/SKILL.md +291 -0
  117. package/hermes-plugin/skills/slm-status/SKILL.md +185 -0
  118. package/hermes-plugin/skills/slm-web-access/SKILL.md +91 -0
  119. package/package.json +9 -18
  120. package/plugin/.claude-plugin/plugin.json +1 -1
  121. package/plugin/.cursor-plugin/plugin.json +1 -1
  122. package/plugin/CLAUDE.md +14 -12
  123. package/plugin/agents/slm-governance-advisor.md +14 -16
  124. package/plugin/agents/slm-loop-runner.md +22 -11
  125. package/plugin/agents/slm-memory-advisor.md +14 -14
  126. package/plugin/agents/slm-optimize-advisor.md +5 -5
  127. package/plugin/commands/slm-loop.md +5 -3
  128. package/plugin/cursor-skills/slm-bot-memory/SKILL.md +19 -12
  129. package/plugin/cursor-skills/slm-getting-started-bot/SKILL.md +17 -9
  130. package/plugin/cursor-skills/slm-recall/SKILL.md +151 -54
  131. package/plugin/cursor-skills/slm-remember/SKILL.md +132 -35
  132. package/plugin/cursor-skills/slm-scope/SKILL.md +24 -17
  133. package/plugin/cursor-skills/slm-session/SKILL.md +77 -57
  134. package/plugin/mcp.cursor.json +1 -1
  135. package/plugin/requirements.txt +1 -1
  136. package/plugin/skills/slm-bot-memory/SKILL.md +19 -12
  137. package/plugin/skills/slm-cache/SKILL.md +6 -7
  138. package/plugin/skills/slm-compress/SKILL.md +3 -3
  139. package/plugin/skills/slm-getting-started-bot/SKILL.md +17 -9
  140. package/plugin/skills/slm-governance/SKILL.md +126 -153
  141. package/plugin/skills/slm-graph/SKILL.md +27 -15
  142. package/plugin/skills/slm-loop/SKILL.md +74 -20
  143. package/plugin/skills/slm-mesh/SKILL.md +17 -12
  144. package/plugin/skills/slm-profile/SKILL.md +101 -92
  145. package/plugin/skills/slm-recall/SKILL.md +151 -54
  146. package/plugin/skills/slm-remember/SKILL.md +132 -35
  147. package/plugin/skills/slm-scope/SKILL.md +24 -17
  148. package/plugin/skills/slm-session/SKILL.md +77 -57
  149. package/plugin/skills/slm-status/SKILL.md +54 -35
  150. package/plugin/skills/slm-web-access/SKILL.md +91 -0
  151. package/plugin-src/agents/slm-governance-advisor.md +78 -0
  152. package/plugin-src/agents/slm-loop-runner.md +82 -0
  153. package/plugin-src/agents/slm-memory-advisor.md +14 -14
  154. package/plugin-src/agents/slm-optimize-advisor.md +5 -5
  155. package/plugin-src/commands/slm-loop.md +33 -0
  156. package/plugin-src/rules/AGENTS.md +45 -36
  157. package/plugin-src/rules/CLAUDE.md.fragment +47 -0
  158. package/plugin-src/skills/slm-bot-memory/SKILL.md +19 -12
  159. package/plugin-src/skills/slm-cache/SKILL.md +6 -7
  160. package/plugin-src/skills/slm-compress/SKILL.md +3 -3
  161. package/plugin-src/skills/slm-getting-started-bot/SKILL.md +17 -9
  162. package/plugin-src/skills/slm-governance/SKILL.md +126 -153
  163. package/plugin-src/skills/slm-graph/SKILL.md +27 -15
  164. package/plugin-src/skills/slm-loop/SKILL.md +74 -20
  165. package/plugin-src/skills/slm-mesh/SKILL.md +17 -12
  166. package/plugin-src/skills/slm-profile/SKILL.md +101 -92
  167. package/plugin-src/skills/slm-recall/SKILL.md +151 -54
  168. package/plugin-src/skills/slm-remember/SKILL.md +132 -35
  169. package/plugin-src/skills/slm-scope/SKILL.md +24 -17
  170. package/plugin-src/skills/slm-session/SKILL.md +77 -57
  171. package/plugin-src/skills/slm-status/SKILL.md +54 -35
  172. package/plugin-src/skills/slm-web-access/SKILL.md +91 -0
@@ -8,7 +8,7 @@ when_to_use: |
8
8
  - "Find stored information about authentication / the database / error handling"
9
9
  - "Search for what I said about Y"
10
10
  - Automatically before any non-trivial task, to surface prior context
11
- allowed-tools: recall, search, fetch, list_recent, Bash
11
+ allowed-tools: recall, search, fetch, list_recent, get_memory_summary, run_view, report_outcome, report_feedback, Bash
12
12
  ---
13
13
 
14
14
  # slm-recall — Search & Retrieve Memory
@@ -26,6 +26,8 @@ multi-channel retrieval. The golden rule: **recall before you remember**.
26
26
  | Exact keyword match needed ("find facts containing BM25") | `search` — FTS5 BM25 only, lower latency |
27
27
  | You have a specific `fact_id` from a prior result | `fetch` — exact lookup, full detail |
28
28
  | Browse newest entries without a query | `list_recent` |
29
+ | A day, a project or a session in readable form | `get_memory_summary` |
30
+ | A question the user saved under a name | `run_view` |
29
31
 
30
32
  Use `recall` as the default. `search` is a fallback for zero-result recall on a
31
33
  known exact term. `fetch` is for when you already know the ID.
@@ -54,18 +56,23 @@ recall(
54
56
  )
55
57
  ```
56
58
 
57
- Real response shape (`--json` equivalent):
59
+ Real response shape (trimmed to the fields that matter; `slm recall --json`
60
+ wraps the same data in a `data` envelope):
58
61
  ```json
59
62
  {
60
63
  "success": true,
61
64
  "results": [
62
65
  {
63
66
  "fact_id": "f8a2bc91",
67
+ "memory_id": "m7e19ca0",
64
68
  "content": "Decided to use JWT with 1h expiry for API auth (2026-06-10)",
65
69
  "score": 0.87,
66
70
  "confidence": 0.91,
67
71
  "trust_score": 0.84,
68
72
  "fact_type": "semantic",
73
+ "memory_kind": "decision",
74
+ "memory_kind_state": "confirmed",
75
+ "age_label": "4 months ago",
69
76
  "channel_scores": {
70
77
  "semantic": 0.88,
71
78
  "bm25": 0.61,
@@ -93,15 +100,25 @@ Real response shape (`--json` equivalent):
93
100
  },
94
101
  "incomplete_channels": [],
95
102
  "retrieval_time_ms": 134,
103
+ "query_id": "q-3f9a",
96
104
  "no_confident_match": false,
97
105
  "calibration_status": "uncalibrated",
98
106
  "calibration_id": null,
99
107
  "answer_confidence": null,
100
108
  "abstained": false,
101
- "abstention_reason": null
109
+ "abstention_reason": null,
110
+ "answer_check_status": "off",
111
+ "answerability": "unjudged",
112
+ "answerability_reason": "disabled"
102
113
  }
103
114
  ```
104
115
 
116
+ Other fields that can appear: `profile` (the namespace that answered),
117
+ `project_scope` (what a `project` filter did), `tag_scope` (what a `tags`
118
+ filter did), `temporal_frame`, `reranker_status`, and `thematic_context`.
119
+ Long contents are clamped and later results can come back as short stubs
120
+ (`truncated` / `stub` on the result); call `fetch` for the full text.
121
+
105
122
  **Read `channel_status` before concluding that nothing is stored.** It reports
106
123
  what each retrieval channel did on this query. `channel_weights` says how much
107
124
  each channel counts; `channel_status` says whether it ran at all.
@@ -114,6 +131,7 @@ each channel counts; `channel_status` says whether it ran at all.
114
131
  | `error` | it raised — **its results are missing from this answer** |
115
132
  | `timeout` | it exceeded its guard — **results missing** |
116
133
  | `no_embedding` | the query could not be embedded, so it could not run |
134
+ | `warming` | the embedding model, or the entity graph, was still loading right after a start — **results missing**, and the same question a little later usually works |
117
135
  | `disabled` | switched off by configuration |
118
136
  | `not_configured` | the backing service is not set up |
119
137
 
@@ -125,14 +143,26 @@ entities in your question, which is why it reports `no_candidates` when the
125
143
  rest come back empty.
126
144
 
127
145
  `empty`, `no_candidates`, `disabled` and `not_configured` are normal. `error`,
128
- `timeout` and `no_embedding` mean the answer is **incomplete, not negative** —
129
- say so to the user rather than reporting "no memories found". `incomplete_channels`
130
- carries the same warning as a plain list.
146
+ `timeout`, `no_embedding` and `warming` mean the answer is **incomplete, not
147
+ negative** — say so to the user rather than reporting "no memories found".
148
+ `incomplete_channels` lists the channels abandoned at the time limit, so two
149
+ runs of the same question that differ only there are an incomplete answer, not
150
+ a changed memory.
131
151
 
132
- **Refine on low confidence.** `recall` returns confidence signals with every result. If `no_confident_match` is `true` (or `answer_confidence` is low / `abstained` is `true`), do NOT invent a memory — rewrite the query into 1–3 more specific sub-queries (split multi-hop questions; try entity names, synonyms, or broader phrasing) and call `recall` again before concluding nothing was found. A confident match → use it directly. SLM answers from this machine in about 1–2 s, with no server-side LLM round — unless the user turned on the online answer check, which adds one request to that service per recall — and lets you, the calling model, drive this refinement.
152
+ **Refine on low confidence.** `recall` returns confidence signals with every result. If `no_confident_match` is `true` (or `answer_confidence` is low / `abstained` is `true`), do NOT invent a memory — rewrite the query into 1–3 more specific sub-queries (split multi-hop questions; try entity names, synonyms, or broader phrasing) and call `recall` again before concluding nothing was found. A confident match → use it directly. SLM answers from this machine, typically in a second or two, with no server-side LLM round — unless the user turned on the online answer check, which adds one request to that service per recall — and lets you, the calling model, drive this refinement.
133
153
 
134
154
  **`abstained` means the results shown do not answer the question.** If `abstained` is `true`, say you don't have it, or ask — never present the returned memories as the answer anyway. `abstention_reason` distinguishes why: `"judged_insufficient"` means candidates were found and scored, but none of them actually answers this question; `"evidence_floor"` / `"no_candidates"` means nothing was found at all. `answer_confidence` is a measurement, not a guarantee — treat a low number the same way you'd treat `abstained: true`. `calibration_status: "uncalibrated"` means no judge is configured for this recall; in that case `abstained` only ever reflects the older "nothing found" signal.
135
155
 
156
+ **`abstained: false` does not mean the answer was checked.** `answerability` says
157
+ whether it was: `supported` (the answer check ran and judged the shown memories
158
+ sufficient), `unsupported` (it ran and judged them insufficient) or `unjudged`
159
+ (it produced no verdict). `answerability_reason` gives the cause: `judged_fresh`
160
+ or `judged_from_memo` for a verdict, and for `unjudged` one of `disabled`,
161
+ `warming`, `unavailable`, `busy`, `budget_exhausted`, `no_results`,
162
+ `not_a_question` or `other_profile`. An empty result set is `unjudged` /
163
+ `no_results`, which is not evidence that no answer exists (check
164
+ `channel_status`). `answer_check_note` carries a sentence you can show a person.
165
+
136
166
  ### 2. Passing session_id
137
167
 
138
168
  Pass the `session_id` returned by `session_init`, on **every** recall in that
@@ -148,21 +178,26 @@ session. It does two things.
148
178
  2. **It attributes engagement to the session**, so a later `report_outcome`
149
179
  can close the loop on the right recall.
150
180
 
151
- Omitting it costs both: recall still returns correct results, but every turn
152
- starts cold and no feedback is attributable.
181
+ If you omit it, SLM looks for `SLM_SESSION_ID`, `CLAUDE_SESSION_ID` or
182
+ `CLAUDE_CODE_SESSION_ID` in the environment, then for the host's registered
183
+ session, and only then falls back to a per-agent label that is never credited
184
+ to a conversation. Recall still returns correct results either way, but a
185
+ fallback label means turns start cold and feedback cannot be attributed.
153
186
 
154
- **Use the real id, not a made-up one.** An id beginning `http:`, `mcp:`, `cli:`
155
- or `probe:` is treated as a synthetic per-request label, not a conversation, and
156
- is excluded from the working set — inventing one per call would otherwise fill
157
- the registry and evict genuine conversations.
187
+ **Use the real id, not a made-up one.** An id beginning `http:`, `mcp:`, `cli:`,
188
+ `probe:`, `engine:`, `agent:`, `api:` or `view:` is treated as a synthetic
189
+ per-request label, not a conversation, and is excluded from the working set —
190
+ inventing one per call would otherwise fill the registry and evict genuine
191
+ conversations.
158
192
 
159
193
  ### 3. Fast mode
160
194
 
161
195
  `fast` controls **one** thing: whether the server runs its own internal LLM
162
196
  reformulation round. It does **not** disable any retrieval channel — every
163
- channel and the reranker run either way. There are four always: meaning,
197
+ channel and the reranker run either way. Four channels register always: meaning,
164
198
  keyword, entity graph and time. Spreading activation and Hopfield register as a
165
- fifth and sixth when their prerequisites are present, so a store sees up to six.
199
+ fifth and sixth when their prerequisites are present, so a store sees up to six
200
+ (`profile` in `channel_status` is a shortcut ahead of them, not a search).
166
201
 
167
202
  Leave it unset. Unset resolves to "skip the internal round", because you are the
168
203
  reasoner: you refine the query yourself using the confidence signals above, and
@@ -178,11 +213,14 @@ recall(query="rate limiting approach", limit=5, session_id="<sid>")
178
213
  When `recall` returns zero results on a specific term, try `search`:
179
214
 
180
215
  ```
181
- search(query="BM25 indexing", limit=10, profile_id="")
216
+ search(query="BM25 indexing", limit=20)
182
217
  ```
183
218
 
184
- `profile_id=""` uses the active profile. Response has `success`, `results`,
185
- and `count` but no `channel_scores` or `query_type`.
219
+ Full-text FTS5 with BM25 ranking, no semantic channel. It takes the same
220
+ `kind`, `tags` / `tags_match` and `profile_id` arguments as `recall` (below).
221
+ The response has `success`, `results` (each with `fact_id`, `content`,
222
+ `fact_type`, `confidence`, `date` and the memory-kind fields) and `count`, but
223
+ no `channel_scores`, `query_type` or answer-check fields.
186
224
 
187
225
  ### 5. Pull full detail for a known fact
188
226
 
@@ -191,44 +229,96 @@ fetch(fact_ids="f8a2bc91,d4c1e203")
191
229
  ```
192
230
 
193
231
  Returns the full record for each ID: `entities`, `lifecycle`, `access_count`,
194
- `importance`, `observation_date`, `referenced_date`. Use this when the recall
232
+ `importance`, `observation_date`, `referenced_date`, `project`. `fact_ids` may be
233
+ a comma-separated string or a list. Ids it could not resolve come back in
234
+ `not_found`; if none resolve, `success` is `false`. Use this when the recall
195
235
  summary (120-char truncation in `list_recent`) is not enough.
196
236
 
197
237
  ### 6. Browse recent memories
198
238
 
199
239
  ```
200
- list_recent(limit=20, profile_id="")
240
+ list_recent(limit=20, kind="", tags="", tags_match="all", profile_id="")
201
241
  ```
202
242
 
203
243
  Returns facts newest-first. Content is truncated to 120 chars. Use `fetch`
204
244
  once you have the `fact_id` for full content.
205
245
 
246
+ ### 7. Narrow a recall
247
+
248
+ Every filter below is optional and composes with the others as AND.
249
+
250
+ | Argument | Effect |
251
+ |---|---|
252
+ | `project` | Only memories saved under that project (a name or a path; case ignored). If none of the memories found were saved under it, the unfiltered results come back and `project_scope.filter.applied` is `false` with a `note` — never a silent empty answer. |
253
+ | `project_strict=True` | With `project`: no fall-back, only that project's memories even if there are none. |
254
+ | `prefer_project` | Ranks memories saved under that project above others of similar relevance and removes nothing. Pass your working directory on every recall in a project. |
255
+ | `saved_by` | Only memories saved by that agent id (for example `claude-desktop`). |
256
+ | `about` | Only memories that mention that person, project or tool. |
257
+ | `kind` | Only memories of one kind: `semantic`, `episodic`, `status`, `opinion`, `rule`, `decision`, `procedure`, `prospective` or `correction`. An unknown value is refused with `INVALID_KIND`. |
258
+ | `tags`, `tags_match` | Only memories saved with these exact labels (a comma-separated string, or a list when a label contains a comma). `tags_match` is `"all"` (default) or `"any"`. Case and spacing do not matter. Unlike `project`, a tag filter never falls back; an empty answer says why in `tag_scope`. |
259
+ | `window` | Event-time range: `"24h"`, `"7d"`, `"30d"`, `"1y"` or `"2026-07-01..2026-07-31"`. An unreadable value is refused. |
260
+ | `as_of`, `known_as_of`, `valid_at` | Point-in-time recall (ISO 8601). `known_as_of` is what SLM knew by then; `valid_at` is what was true then. `include_unknown=True` also admits older memories with no recorded time provenance. |
261
+ | `profile_id` | Serve this one call from another existing profile without moving the active one. |
262
+
263
+ Questions phrased like "what did we decide", "how do I" or "what is the current
264
+ status of" are answered with decisions, how-tos and the newest current-state
265
+ memory first, without any filter.
266
+
267
+ ```
268
+ recall(query="rollback procedure", kind="procedure", tags="ops", prefer_project="/work/api", session_id="<sid>")
269
+ ```
270
+
271
+ ### 8. Summaries and saved views
272
+
273
+ `get_memory_summary(kind="day", target="")` returns a readable summary of a
274
+ `day` (an ISO date, `today` or `yesterday`), a `project` (a directory path), a
275
+ `session` (a session id; leave `target` empty to get `recent_sessions` to pick
276
+ from) or a `community` (the `community_id` a recall gave in `thematic_context`).
277
+ It comes with `coverage` and `source_fact_ids`; session data is sparse, so do
278
+ not present a partial summary as a complete record.
279
+
280
+ `run_view(name="")` lists the user's saved views; with a name it runs that
281
+ saved question through ordinary recall, and the same `no_confident_match` rule
282
+ applies. Views are created from the dashboard, with `slm view create`, or with
283
+ `manage_view`.
284
+
206
285
  ---
207
286
 
208
- ### 7. Close the loop — say which memories helped
287
+ ### 9. Close the loop — say which memories helped
209
288
 
210
- Retrieval ranks a memory partly on whether it has actually been useful before.
211
- That evidence only exists if you supply it.
289
+ Whether a memory has been useful is evidence SLM records only if you supply it.
290
+ It is stored as learning signals (the count shows in `session_init`'s `learning`
291
+ block and on the dashboard). Signals reorder results only where adaptive ranking
292
+ is switched on by the operator (`SLM_RANKING`); it is off unless set, so do not
293
+ promise the user that a report changes the next answer.
212
294
 
213
295
  ```
214
296
  report_outcome(
215
297
  memory_ids="f8a2bc91,c31d0f77", # the ids you actually used
216
298
  outcome="success", # "success" | "failure" | "partial"
217
299
  context="used the JWT expiry decision to write the refresh handler",
300
+ recall_query_id="q-3f9a", # the query_id of the recall; ties the report to that answer
218
301
  )
219
302
  ```
220
303
 
304
+ `report_outcome` and `report_feedback` are not in the smallest (`core`) tool set.
305
+ If your host does not list them, skip this step; nothing else depends on it.
306
+
221
307
  Call it when a recall visibly changed what you did: you applied the decision,
222
308
  followed the convention, or avoided the gotcha. Report `failure` when a
223
309
  confidently-returned memory turned out to be wrong or stale — a negative signal
224
- is worth as much as a positive one, and it is the only way a stale memory stops
225
- being promoted.
310
+ is recorded the same as a positive one. To retire a stale memory outright, save
311
+ the new version with `replaces` (see `slm-remember`).
226
312
 
227
313
  Report only ids you genuinely used. Reporting every returned id marks the
228
- irrelevant ones useful and trains the ranker toward noise.
314
+ irrelevant ones useful and records noise as signal. Without `recall_query_id`
315
+ the report is matched to a recall by overlapping memory ids within a time window.
229
316
 
230
317
  `report_feedback(fact_id, feedback, query)` is the finer-grained form for a
231
- single fact and the query that surfaced it.
318
+ single fact and the query that surfaced it; `feedback` is `"relevant"` (the
319
+ default), `"irrelevant"` or `"partial"`. If the signal could not be written to
320
+ the learning store it answers `success: false` with `durable: false`: do not
321
+ tell the user it was recorded.
232
322
 
233
323
  ---
234
324
 
@@ -238,8 +328,8 @@ single fact and the query that surfaced it.
238
328
  keyword matching, temporal recency weighting, and contextual graph channels — then
239
329
  fuses and reranks the combined results, with an optional entity-graph score
240
330
  enhancement. The `channel_weights` field in the response shows how each channel
241
- contributed for that query. Weights adapt over time based on engagement signals
242
- attributed via `session_id`.
331
+ contributed for that query. Adaptive re-weighting from engagement signals is an
332
+ operator opt-in (`SLM_RANKING`) and is off by default.
243
333
 
244
334
  To inspect per-channel scores for a real query against your own data:
245
335
 
@@ -254,35 +344,40 @@ No benchmark numbers are cited here; performance is workload-dependent.
254
344
  ## CLI fallback (when MCP is unavailable)
255
345
 
256
346
  ```bash
257
- # Multi-channel semantic recall
258
- slm recall "<query>" [--limit N] [--fast] [--json]
347
+ # Multi-channel recall
348
+ slm recall "<query>" [--limit N] [--json]
259
349
 
260
- # Opt into shared/global facts for one query (v3.6.15 — off by default)
261
- slm recall "<query>" --include-global --include-shared
350
+ # Narrow it (all optional, combined as AND)
351
+ slm recall "<query>" --project <name-or-path> [--project-strict] [--prefer-project <path>]
352
+ slm recall "<query>" --kind decision --tag auth --tag security [--tags-match any]
353
+ slm recall "<query>" --saved-by claude-desktop --about "Alice" --window 7d
354
+ slm recall "<query>" --as-of 2026-01-01T00:00:00+00:00 [--known-as-of ...] [--valid-at ...] [--include-unknown]
262
355
 
263
- # Keyword/FTS5 search (alias: slm search)
264
- slm search "<query>" [--limit N] [--json]
356
+ # Opt into shared/global facts for one query (off by default)
357
+ slm recall "<query>" --include-global --include-shared
265
358
 
266
359
  # Per-channel score breakdown
267
360
  slm trace "<query>" [--limit N] [--json]
268
361
 
269
- # Browse recent memories
270
- slm list [--limit N] [--json]
362
+ # Browse recent memories; each line shows the memory's kind and its id
363
+ slm list [--limit N] [--kind KIND] [--tag LABEL ...] [--tags-match all|any] [--json]
364
+
365
+ # Summaries and saved views
366
+ slm summary day [today|yesterday|YYYY-MM-DD] | project <path> | session <id> | sessions [--json]
367
+ slm view list | create <name> "<query>" [--kind K --window W --limit N] | run <name> | show <name> | rename <name> <new> | delete <name>
271
368
  ```
272
369
 
273
- Flags verified in source (main.py):
274
- - `slm recall`: `--limit`, `--fast`, `--json`, `--include-global` / `--no-global`, `--include-shared` / `--no-shared`
275
- - `slm search`: `--limit`, `--json`
276
- - `slm trace`: `--limit`, `--json`
277
- - `slm list`: `--limit` / `-n`, `--json`
370
+ `slm search` is an alias of `slm recall`: it runs the same multi-channel
371
+ retrieval, not the FTS5-only keyword search the MCP `search` tool performs.
372
+ `--fast` forces the quick path; it is already the default for agents.
278
373
 
279
- > **Multi-scope (v3.6.15, opt-in):** recall is shared-OFF by default — it returns only
280
- > this profile's facts. Pass `--include-global` / `--include-shared` (or the MCP
281
- > `include_global` / `include_shared` args) to opt in for a query, or set the defaults in
282
- > your `mode_a/b/c.json` config. See [docs/shared-memory.md](../../../docs/shared-memory.md).
374
+ Flags that do **not** exist on `slm recall`: `--min-score`, `--format`,
375
+ `--tags` (the flag is the repeatable `--tag`).
283
376
 
284
- **Flags that do NOT exist** (fabricated in old skills — never write these):
285
- `--min-score`, `--format`, `--project`, `--tags` on recall or search.
377
+ Recall returns only this profile's own memories unless you pass
378
+ `--include-global` / `--include-shared` (or the MCP `include_global` /
379
+ `include_shared` arguments), or the user has set the defaults in their
380
+ configuration. See [docs/shared-memory.md](../../../docs/shared-memory.md).
286
381
 
287
382
  ---
288
383
 
@@ -294,7 +389,7 @@ trusts that what you surface came from the store.
294
389
 
295
390
  ---
296
391
 
297
- ## Multi-scope retrieval (v3.6.15+, opt-in)
392
+ ## Shared and global memories (opt-in)
298
393
 
299
394
  By default `recall` returns only memories in the active profile (personal scope).
300
395
  To also surface memories shared from other profiles, pass the scope flags:
@@ -313,11 +408,13 @@ to see shared or global facts. See `slm-scope` for the full sharing model.
313
408
 
314
409
  ---
315
410
 
316
- ## Profile-aware retrieval (v3.8.0+)
411
+ ## Profile-aware retrieval
317
412
 
318
- `recall` always queries the currently active profile. To query a different
319
- workspace, use `switch_profile` (requires `code`, `full`, or `power` MCP profile)
320
- before recalling, then switch back. See `slm-profile` for workspace switching.
413
+ `recall` queries the active profile. To read another existing profile for one
414
+ call, pass `profile_id="<name>"` (the active profile is not moved). The
415
+ `switch_profile` tool changes the active profile for every later call and for
416
+ other sessions on this machine, so reserve it for when the user asks to move.
417
+ See `slm-profile`.
321
418
 
322
419
  ---
323
420
 
@@ -330,4 +427,4 @@ before recalling, then switch back. See `slm-profile` for workspace switching.
330
427
 
331
428
  ---
332
429
 
333
- *SuperLocalMemory v4.1.22 · Qualixar · AGPL-3.0-or-later*
430
+ *SuperLocalMemory v4.1.23 · Qualixar · AGPL-3.0-or-later*
@@ -8,7 +8,7 @@ when_to_use: |
8
8
  - "Note this as a gotcha / blocker / convention"
9
9
  - After making a non-obvious decision during a coding session
10
10
  - After resolving a bug whose root cause should be persisted
11
- allowed-tools: remember, recall, update_memory, Bash
11
+ allowed-tools: remember, recall, update_memory, set_memory_kind, review_memory_kinds, confirm_memory_kinds, list_corrections, review_correction, delete_memory, Bash
12
12
  ---
13
13
 
14
14
  # slm-remember — Capture Durable Facts
@@ -39,9 +39,14 @@ sessions. One fact per call. Recall before you remember.
39
39
  Before calling `remember`, always call `recall` first with the core terms of
40
40
  what you are about to store. If a near-duplicate exists:
41
41
 
42
- - Use `update_memory(fact_id, content)` to refine the existing fact instead
43
- of creating a new one.
44
- - Only call `remember` when no sufficiently similar fact is found.
42
+ - If the new text **replaces** the old one (a status that moved on, a decision
43
+ that changed, a rule that was reworded), save it with
44
+ `remember(..., replaces="<fact_id>")`. It takes effect at once and can be
45
+ undone.
46
+ - If you are **correcting** the old memory and want a person to approve the
47
+ change, use `update_memory(fact_id, content)`. This opens a correction for
48
+ review; it does not overwrite anything (see "Updating a memory" below).
49
+ - Only call `remember` with neither when no sufficiently similar fact is found.
45
50
 
46
51
  Duplicates degrade retrieval quality for every future session.
47
52
 
@@ -58,13 +63,19 @@ recall(query="JWT token expiry auth", limit=5, session_id="<sid>")
58
63
  If a near-duplicate is returned:
59
64
 
60
65
  ```
61
- update_memory(
62
- fact_id="f8a2bc91",
63
- content="JWT tokens use 1h expiry for API access tokens; refresh tokens 30d (updated 2026-06-16)",
66
+ remember(
67
+ content="JWT tokens use 1h expiry for API access tokens; refresh tokens 30d",
68
+ tags="auth,security,decision",
69
+ project="superlocalmemory",
70
+ kind="decision",
71
+ replaces="f8a2bc91",
64
72
  )
65
73
  ```
66
74
 
67
- `update_memory` returns `{"success": true, "fact_id": "f8a2bc91", "content": "..."}`.
75
+ The old memory is retired, not deleted: recall stops returning it and it is no
76
+ longer loaded at session start. The response's `replaced` says what was retired,
77
+ or why nothing was (the new memory is saved either way). An unknown id, or an id
78
+ from another profile, is refused before anything is saved.
68
79
 
69
80
  ### 2. Store a new fact
70
81
 
@@ -85,12 +96,25 @@ Real response shape:
85
96
  "fact_ids": ["c9d4e112"],
86
97
  "count": 1,
87
98
  "pending": false,
88
- "message": "Stored (recallable now; enriching async)."
99
+ "pending_id": null,
100
+ "operation_id": "op-7c21",
101
+ "materialization_state": "complete",
102
+ "message": "Stored through canonical daemon ingestion."
89
103
  }
90
104
  ```
91
105
 
92
- When `pending: true`, the daemon was offline at save time; the fact enters a
93
- pending queue and becomes recallable once the daemon is back. Do not re-save.
106
+ `pending: true` with `materialization_state` `queryable` or `enriching` means the
107
+ memory is already stored and findable by its words while enrichment finishes;
108
+ do not re-save. A reply with `materialization_state: "accepted"` and `count: 0`
109
+ means the memory is durable but the writer was busy; it becomes searchable
110
+ within seconds, and resending the same `idempotency_key` returns the final
111
+ receipt. When the call used `replaces` the reply carries `replaced`; when the
112
+ same words were already saved under another confirmed kind it carries
113
+ `kind_conflict` and keeps that kind.
114
+
115
+ Failures come back as `success: false` with a `code` and `retryable`:
116
+ `DAEMON_UNAVAILABLE` (`retryable: true`), `INVALID_KIND`, `NOT_AUTHORIZED`, or an
117
+ unknown-profile / unknown-`replaces` refusal (`retryable: false`).
94
118
 
95
119
  **Never claim "saved" unless `success: true` is in the response.**
96
120
 
@@ -104,14 +128,18 @@ remember(
104
128
  importance: int = 5,# 1–10; see scale below
105
129
  session_id: str = "",# from session_init; attributes the write to this session
106
130
  session_date: str = "",# when the memory is ABOUT, if not today
107
- scope: str = None, # v3.6.15 multi-scope: "personal" (default) | "shared" | "global"
131
+ scope: str = None, # "personal" (default) | "shared" | "global"
108
132
  shared_with: str = "",# comma-separated profile_ids for scope="shared"
109
133
  idempotency_key: str = "",# replaying the same key will not store a second copy
134
+ kind: str = "", # what sort of memory this is; see "Say what kind it is"
135
+ replaces: str = None,# fact_id (or memory_id) of the earlier memory this one replaces
136
+ profile_id: str = "",# write to another existing profile; "" = the active one
137
+ agent_id: str = "mcp_client", # attribution; resolved from the connection when left alone
110
138
  )
111
139
  ```
112
140
 
113
- > **Multi-scope (v3.6.15, opt-in):** leave `scope` unset for `personal` (private to
114
- > this profile — the default, identical to 3.6.14). `"global"` is visible to every
141
+ > **Multi-scope (opt-in):** leave `scope` unset for `personal` (private to
142
+ > this profile — the default, the same as a single-profile install). `"global"` is visible to every
115
143
  > profile on the machine; `"shared"` is visible to the profiles in `shared_with`.
116
144
  > See [docs/shared-memory.md](../../../docs/shared-memory.md).
117
145
 
@@ -147,31 +175,87 @@ event time, so a mis-dated memory is one a time-scoped question cannot find.
147
175
  describes something planned — "the migration is scheduled for Tuesday", "the
148
176
  certificate expires on 2026-09-01" — is stored as a **prospective** memory, and
149
177
  recall reports it as `"fact_type": "prospective"`. That is inferred from how the
150
- content reads, not from the date you pass. Stores written before 4.1.0 spelled
151
- this type `"temporal"`; that value still reads correctly and needs nothing from
152
- you.
178
+ content reads, not from the date you pass. Older stores spelled this type
179
+ `"temporal"`; that value still reads correctly and needs nothing from you.
153
180
 
154
181
  ---
155
182
 
156
- ### 5. One fact per call
183
+ ### 5. Say what kind it is
184
+
185
+ `kind` is one of nine values: `rule` (a standing instruction: "always/never
186
+ ..."), `decision` (a choice that settles a question), `status` (the current
187
+ state of something, which a later update will replace), `procedure` (steps or
188
+ commands), `prospective` (a plan or to-do), `opinion` (a preference or view),
189
+ `correction` (says an earlier memory was wrong), `episodic` (something that
190
+ happened) or `semantic` (a lasting fact). An unknown value is refused with
191
+ `INVALID_KIND` before anything is saved.
192
+
193
+ Set it whenever you know. A kind you declare is confirmed, and confirmed rules
194
+ (up to 10) and confirmed decisions (up to 5) are loaded by `session_init` at
195
+ the start of later sessions. Leave `kind` empty when unsure: SLM may suggest
196
+ one later, and a suggestion changes nothing until someone confirms it. Never
197
+ set a kind just to get a memory loaded at session start.
198
+
199
+ Manage kinds after the fact:
200
+
201
+ | Tool | Use |
202
+ |---|---|
203
+ | `set_memory_kind(fact_id, kind)` | Set and confirm the kind of one memory you know the type of |
204
+ | `review_memory_kinds(kind="", limit=20)` | List suggestions waiting for confirmation (limit 1–100) |
205
+ | `confirm_memory_kinds(items)` | Confirm up to 200 at once; each item is `{"fact_id": ..., "kind": ...}`, and omitting `kind` accepts the suggestion |
206
+ | `memory_kinds_status()` | Counts per kind, the classifying backend, any run in progress |
207
+
208
+ CLI: `slm remember "<text>" --kind rule`, `slm kinds status|set|review|confirm`,
209
+ `slm kinds backfill start|pause|resume|cancel|revert|status`, and
210
+ `slm kinds settings` (backend, standing rules on or off). Classifying with Jev
211
+ sends memory text online and needs its own consent (`--jev-consent yes`).
212
+
213
+ ### 6. Updating a memory: `replaces` versus `update_memory`
214
+
215
+ `update_memory(fact_id, content)` and `slm update <fact_id> "<new text>"` do not
216
+ overwrite a memory. They keep the original and propose a correction: the reply
217
+ has `predecessor_fact_id`, `successor_fact_id`, `correction_case` (with
218
+ `case_id`, `status`, `version`) and `review_required: true`. Until a person
219
+ applies the case, **the original stays current and the new text is not
220
+ returned by recall**. A memory can have only one open correction at a time; a
221
+ second edit is refused with a message naming the open case.
222
+
223
+ Review cases with `list_corrections(limit=100)` and
224
+ `review_correction(case_id, action, expected_version)`, where `action` is
225
+ `apply`, `reject` or `rollback` and `expected_version` is the case's current
226
+ `version`. `apply` retires the original and admits the new text; `rollback`
227
+ undoes an applied case (including one made by `replaces`). CLI:
228
+ `slm review-correction <case_id> apply|reject|rollback <expected_version>`.
229
+
230
+ Two rules about SLM's own guesses. When it saves a memory that looks like an
231
+ update to an older one, it may file a correction case of its own. That guess
232
+ never hides the memory you saved: both stay findable until a person reviews it,
233
+ approving retires the older one, and rejecting keeps both. And if you edit,
234
+ replace or delete a memory that only such an unreviewed machine guess names,
235
+ your action wins and the guess is closed as overtaken (`slm corrections
236
+ overtaken` lists them, `slm corrections restore-overtaken <case_id>` puts one
237
+ back). A correction a person proposed, or one already decided, is kept
238
+ permanently and protects the memories in it from being deleted.
239
+
240
+ ### 7. One fact per call
157
241
 
158
242
  Store one atomic fact per `remember` call. Do not concatenate multiple unrelated
159
243
  points into a single content string — they will be hard to update individually
160
244
  and harder to retrieve cleanly. If you have three separate decisions, make three
161
245
  calls.
162
246
 
163
- ### 6. Always set tags and project
247
+ ### 8. Always set tags and project
164
248
 
165
249
  Untagged, unscoped facts are harder to retrieve and harder to manage. Minimum:
166
250
  set `tags` to one or two relevant terms and `project` to the repo/product name.
167
251
 
168
252
  ---
169
253
 
170
- ## Deleting stale facts via CLI
254
+ ## Deleting stale facts
171
255
 
172
- For deletion, the CLI is the authoritative surface. The MCP `forget` tool in
173
- v3.6.14 runs an Ebbinghaus decay cycle — it does NOT delete by query. For
174
- targeted deletion, use the CLI:
256
+ The MCP `forget(dry_run=True)` tool runs an Ebbinghaus decay cycle over the
257
+ whole profile — it does NOT delete by query. To delete one memory you have the
258
+ id of, call `delete_memory(fact_id)`. To delete by query, use the CLI:
175
259
 
176
260
  ```bash
177
261
  # Preview what would be deleted (always do this first)
@@ -189,6 +273,8 @@ Flags verified in source (main.py):
189
273
  - `slm delete`: positional `fact_id`, `--yes` / `-y`, `--json`
190
274
 
191
275
  Always run `--dry-run` first and review the preview before passing `--yes`.
276
+ A memory that belongs to a reviewed correction cannot be deleted (it is refused
277
+ with the case ids and nothing is changed). Treat every other deletion as permanent.
192
278
 
193
279
  ---
194
280
 
@@ -196,13 +282,20 @@ Always run `--dry-run` first and review the preview before passing `--yes`.
196
282
 
197
283
  ```bash
198
284
  # Store a fact
199
- slm remember "<content>" [--tags a,b,c] [--json]
285
+ slm remember "<content>" [--tags a,b,c] [--kind rule|decision|...] [--json]
286
+
287
+ # Replace an earlier memory (takes effect at once; undo with review-correction)
288
+ slm remember "<content>" --replaces <fact_id> --kind status
200
289
 
201
- # Store a shared/global fact (v3.6.15, opt-in)
290
+ # Store a shared/global fact (opt-in)
202
291
  slm remember "<content>" --scope global
203
292
  slm remember "<content>" --scope shared --shared-with alice,bob
204
293
 
205
- # Flags verified in source (main.py): --tags, --json, --sync, --scope, --shared-with
294
+ # Propose a reviewed correction instead of replacing
295
+ slm update <fact_id> "<new text>"
296
+ slm review-correction <case_id> apply|reject|rollback <expected_version>
297
+
298
+ # Flags: --tags, --kind, --replaces, --json, --sync, --scope, --shared-with
206
299
  # --sync: wait for full enrichment before returning (default is async)
207
300
  # --scope: personal (default) | shared | global ; --shared-with: profile ids for shared
208
301
  ```
@@ -216,14 +309,15 @@ slm remember "<content>" --scope shared --shared-with alice,bob
216
309
 
217
310
  | Scenario | Action |
218
311
  |----------|--------|
219
- | Fact is still true but needs refinement | `update_memory(fact_id, new_content)` |
220
- | Fact is superseded or wrong | `slm forget "<query>" --dry-run` then `--yes` |
221
- | Duplicate found that matches recall result | `update_memory` on the existing one |
222
- | Fact has a known ID and is clearly obsolete | `slm delete <fact_id> --yes` |
312
+ | Fact has changed and the new version should win now | `remember(..., replaces="<fact_id>")` |
313
+ | Fact needs a correction a person should approve | `update_memory(fact_id, new_content)`, then `review_correction` |
314
+ | Duplicate found that matches recall result | `replaces` the existing one, or leave it |
315
+ | Fact is wrong and should disappear | `slm forget "<query>" --dry-run` then `--yes` |
316
+ | Fact has a known ID and is clearly obsolete | `delete_memory(fact_id)` or `slm delete <fact_id> --yes` |
223
317
 
224
318
  ---
225
319
 
226
- ## Multi-scope sharing (v3.6.15+, opt-in)
320
+ ## Sharing across profiles (opt-in)
227
321
 
228
322
  Every `remember` call defaults to `personal` scope — private to the active profile.
229
323
  To share a fact with other profiles on the same machine, set the `scope` parameter:
@@ -254,10 +348,13 @@ complete sharing model and when to use each scope.
254
348
 
255
349
  ---
256
350
 
257
- ## Profile-aware storage (v3.8.0+)
351
+ ## Profile-aware storage
258
352
 
259
- `remember` always stores in the active profile's namespace. To write to a
260
- different workspace, use `switch_profile` first. See `slm-profile`.
353
+ `remember` stores in the active profile. To write one memory to another existing
354
+ profile, pass `profile_id="<name>"`; an unknown name is rejected, never created.
355
+ `switch_profile` moves the active profile for every later call and for other
356
+ sessions on this machine, so use it only when the user asks to move. See
357
+ `slm-profile`.
261
358
 
262
359
  ---
263
360
 
@@ -270,4 +367,4 @@ different workspace, use `switch_profile` first. See `slm-profile`.
270
367
 
271
368
  ---
272
369
 
273
- *SuperLocalMemory v4.1.22 · Qualixar · AGPL-3.0-or-later*
370
+ *SuperLocalMemory v4.1.23 · Qualixar · AGPL-3.0-or-later*