memory-lab-mcp 0.1.1__tar.gz

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 (35) hide show
  1. memory_lab_mcp-0.1.1/LICENSE +21 -0
  2. memory_lab_mcp-0.1.1/MANIFEST.in +8 -0
  3. memory_lab_mcp-0.1.1/PKG-INFO +449 -0
  4. memory_lab_mcp-0.1.1/README.md +424 -0
  5. memory_lab_mcp-0.1.1/pyproject.toml +48 -0
  6. memory_lab_mcp-0.1.1/setup.cfg +4 -0
  7. memory_lab_mcp-0.1.1/src/claude_memory_lab/__init__.py +3 -0
  8. memory_lab_mcp-0.1.1/src/claude_memory_lab/auto_memory_import.py +427 -0
  9. memory_lab_mcp-0.1.1/src/claude_memory_lab/cjk_glossary.py +197 -0
  10. memory_lab_mcp-0.1.1/src/claude_memory_lab/cli.py +743 -0
  11. memory_lab_mcp-0.1.1/src/claude_memory_lab/config.py +152 -0
  12. memory_lab_mcp-0.1.1/src/claude_memory_lab/db.py +245 -0
  13. memory_lab_mcp-0.1.1/src/claude_memory_lab/entities.py +110 -0
  14. memory_lab_mcp-0.1.1/src/claude_memory_lab/entrypoint.py +123 -0
  15. memory_lab_mcp-0.1.1/src/claude_memory_lab/eval.py +772 -0
  16. memory_lab_mcp-0.1.1/src/claude_memory_lab/host_hooks.py +1472 -0
  17. memory_lab_mcp-0.1.1/src/claude_memory_lab/ingest.py +958 -0
  18. memory_lab_mcp-0.1.1/src/claude_memory_lab/mcp_server.py +551 -0
  19. memory_lab_mcp-0.1.1/src/claude_memory_lab/memory.py +587 -0
  20. memory_lab_mcp-0.1.1/src/claude_memory_lab/memory_scope.py +678 -0
  21. memory_lab_mcp-0.1.1/src/claude_memory_lab/paths.py +77 -0
  22. memory_lab_mcp-0.1.1/src/claude_memory_lab/project_lifecycle.py +770 -0
  23. memory_lab_mcp-0.1.1/src/claude_memory_lab/redact.py +97 -0
  24. memory_lab_mcp-0.1.1/src/claude_memory_lab/risk_keywords.txt +17 -0
  25. memory_lab_mcp-0.1.1/src/claude_memory_lab/search.py +606 -0
  26. memory_lab_mcp-0.1.1/src/claude_memory_lab/text.py +125 -0
  27. memory_lab_mcp-0.1.1/src/claude_memory_lab/version.py +15 -0
  28. memory_lab_mcp-0.1.1/src/claude_memory_lab/wiki.py +627 -0
  29. memory_lab_mcp-0.1.1/src/claude_memory_lab/wiring.py +572 -0
  30. memory_lab_mcp-0.1.1/src/memory_lab_mcp.egg-info/PKG-INFO +449 -0
  31. memory_lab_mcp-0.1.1/src/memory_lab_mcp.egg-info/SOURCES.txt +33 -0
  32. memory_lab_mcp-0.1.1/src/memory_lab_mcp.egg-info/dependency_links.txt +1 -0
  33. memory_lab_mcp-0.1.1/src/memory_lab_mcp.egg-info/entry_points.txt +3 -0
  34. memory_lab_mcp-0.1.1/src/memory_lab_mcp.egg-info/requires.txt +4 -0
  35. memory_lab_mcp-0.1.1/src/memory_lab_mcp.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Harvey Chan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ # Tests are deliberately not shipped. setuptools picks them up by default, but
2
+ # it does not pick up `tests/fixtures/` or `eval/`, so the sdist would carry a
3
+ # suite that cannot pass — worse than no suite at all. Run them from a clone.
4
+ prune tests
5
+ prune eval
6
+ prune ui
7
+ prune docs
8
+ prune integrations
@@ -0,0 +1,449 @@
1
+ Metadata-Version: 2.4
2
+ Name: memory-lab-mcp
3
+ Version: 0.1.1
4
+ Summary: Local-first Agent Knowledge curation and evidence index
5
+ Author: Harvey Chan
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/haru3613/memory-lab
8
+ Project-URL: Source, https://github.com/haru3613/memory-lab
9
+ Project-URL: Issues, https://github.com/haru3613/memory-lab/issues
10
+ Keywords: memory,mcp,agents,claude,codex,retrieval
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: mcp>=1.2
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest>=8.0; extra == "dev"
24
+ Dynamic: license-file
25
+
26
+ # Memory Lab
27
+
28
+ Local-first Agent Knowledge curation and evidence search for Claude Code, Codex, OpenClaw, and Hermes.
29
+
30
+ Obsidian Markdown under `Agent Knowledge/` is the curated source of truth. Memory Lab's SQLite evidence index is disposable and rebuildable; its legacy memory tables remain available for rollback and inspection during migration.
31
+
32
+ Memory Lab stores no provider API key. Automatic curation invokes the
33
+ already-authenticated agent host CLI.
34
+
35
+ ## Operating model
36
+
37
+ Keep these layers separate:
38
+
39
+ - **Capture Notes** — append-only Markdown preferences, decisions, lessons, and
40
+ references; the authoritative durable record.
41
+ - **Wiki Projection** — rebuildable entity, concept, and source-index pages with
42
+ evidence-backed wikilinks.
43
+ - **SQLite** — a derived search index and legacy rollback surface.
44
+
45
+ Every new memory belongs to exactly one primary entity: `USER`, `AGENT`,
46
+ `APP`, or `RUN`. Its semantic kind and writer remain separate fields. Existing
47
+ project memory maps to `APP`; Obsidian Markdown remains authoritative.
48
+
49
+ Agents can add durable knowledge through the append-only `memory_remember` MCP
50
+ tool, the explicit `promote` CLI workflow, or an installed lifecycle hook whose
51
+ isolated host-model curator produces a validated candidate and indexed receipt.
52
+
53
+ ## Install
54
+
55
+ ```bash
56
+ # Stable release from PyPI:
57
+ uv tool install memory-lab-mcp
58
+
59
+ # Today, and for tracking main (needs git credentials while the repo is private):
60
+ uv tool install git+https://github.com/haru3613/memory-lab@main
61
+ ```
62
+
63
+ Then check it:
64
+
65
+ ```bash
66
+ memory-lab --version
67
+ memory-lab stats # prints the store, config file and corpora it resolved
68
+ ```
69
+
70
+ `pipx install memory-lab-mcp` works the same way. The installed commands remain
71
+ `memory-lab` and `claude-memory-lab`, so host configs do not depend on the PyPI
72
+ distribution name.
73
+
74
+ ### Update
75
+
76
+ For installations already using the PyPI distribution:
77
+
78
+ ```bash
79
+ uv tool upgrade memory-lab-mcp
80
+ ```
81
+
82
+ Nothing else. Host configs are written with an absolute path to the installed
83
+ entry point, so an upgrade swaps the code behind a path that does not move —
84
+ no re-wiring, no re-running setup.
85
+
86
+ The unpublished development builds used `memory-lab` as their distribution
87
+ name. Migrate those in this order so two distributions never own the same
88
+ commands or Python package:
89
+
90
+ ```bash
91
+ uv tool uninstall memory-lab
92
+ uv tool install memory-lab-mcp
93
+ ```
94
+
95
+ One caveat: setup records the entry point beside the interpreter that ran it.
96
+ Install with `uv tool` or `pipx` and that path is stable. Run setup from a
97
+ project venv instead and the hook points into that venv, so recreating it
98
+ means re-running `setup-hooks`.
99
+
100
+ Upgrading from the still older `claude-memory-lab` distribution? Uninstall it
101
+ before installing `memory-lab-mcp` for the same reason.
102
+
103
+ ### Configure
104
+
105
+ Corpora are opt-in. An unconfigured install indexes nothing, which is the
106
+ privacy default rather than a bug. Create `~/.config/memory-lab/config.toml`:
107
+
108
+ ```toml
109
+ [projects]
110
+ my-project = "~/.claude/projects/-Users-me-code-my-project"
111
+
112
+ # Optional. Found automatically on macOS with iCloud.
113
+ [obsidian]
114
+ vault = "~/path/to/your/vault"
115
+ ```
116
+
117
+ Only the `Agent Knowledge/` folder of a vault is ever read. That boundary is
118
+ not configurable.
119
+
120
+ ### Wire up your agents
121
+
122
+ Claude Code and Codex, in one command:
123
+
124
+ ```bash
125
+ memory-lab init --dry-run # prints the plan, changes nothing
126
+ memory-lab init
127
+ memory-lab doctor # exits non-zero on any problem
128
+ ```
129
+
130
+ `init` refuses rather than writing a command it could not prove runnable, so a
131
+ successful run means the hooks work — including from a shell with no PATH. It
132
+ names every file it changed and where it backed each one up. `--uninstall`
133
+ reverses it.
134
+
135
+ OpenClaw and Hermes load a plugin bundle instead of hooks, so they install
136
+ through their own plugin channels:
137
+
138
+ ```bash
139
+ openclaw plugins install memory-lab --marketplace https://github.com/haru3613/memory-lab
140
+ hermes plugins install haru3613/memory-lab-hermes --enable && hermes memory setup memory-lab
141
+ ```
142
+
143
+ Hermes also needs the package inside its own interpreter — it loads the
144
+ provider in-process:
145
+ `uv pip install --python ~/.hermes/hermes-agent/venv/bin/python memory-lab-mcp`.
146
+ If that interpreter has the unpublished `memory-lab` distribution, remove it
147
+ before this install; see the migration command in the wiring guide.
148
+
149
+ `memory-lab doctor` checks all four, including whether a plugin would open a
150
+ different database from the one your hooks write to. Details and the reasoning
151
+ behind each step: [docs/wiring](docs/wiring/README.md).
152
+
153
+ ### Develop
154
+
155
+ ```bash
156
+ python3.11 -m venv .venv && .venv/bin/pip install -e ".[dev]"
157
+ .venv/bin/python -m pytest
158
+ ```
159
+
160
+ Setup merges four owned lifecycle hooks into `~/.codex/hooks.json` or
161
+ `~/.claude/settings.json` without replacing unrelated hooks. Repeating setup is
162
+ safe; remove only Memory Lab's entries with the matching
163
+ `setup-hooks --host <host> --uninstall`.
164
+
165
+ Codex requires a one-time human trust decision before user hooks execute. After
166
+ setup, open Codex, run `/hooks`, review the four commands marked
167
+ `MEMORY_LAB_HOOK=1`, and approve them. User hooks run outside the sandbox;
168
+ Memory Lab does not write Codex's private trust hashes or install a permanent
169
+ trust bypass.
170
+
171
+ The automatic loop is:
172
+
173
+ - `SessionStart`: retry pending durable captures and repair the Wiki Projection.
174
+ - `UserPromptSubmit`: resolve the active USER, AGENT, APP, and RUN identities,
175
+ search their exact union, and inject relevant context.
176
+ - `Stop`: persist a bounded, secret-redacted user/assistant transcript capture,
177
+ run an isolated host-model curator, and write
178
+ only 0–3 validated preferences, decisions, lessons, or references through
179
+ `memory_remember`, each assigned to one primary entity, then rebuild the Wiki
180
+ Projection.
181
+ - `PreCompact`: Claude Code captures before context compaction; both hosts retry
182
+ pending captures and rebuild the Wiki Projection.
183
+
184
+ Tool output is excluded from captures. Obsidian is updated only when
185
+ `memory_remember` returns an indexed receipt; failures remain pending in SQLite
186
+ and retry on a later lifecycle event. An unrecognized Git repository with an
187
+ origin remote is onboarded automatically; unsafe or unidentifiable directories
188
+ receive explicit manual guidance instead of silently skipping the memory loop.
189
+ Claude's curator runs in safe mode with tools and session persistence disabled.
190
+
191
+ ## Obsidian vault contract
192
+
193
+ Memory Lab traverses exactly one top-level folder in the existing vault:
194
+
195
+ ```text
196
+ Agent Knowledge/
197
+ ├── _Index.md
198
+ ├── Users/
199
+ ├── Agents/
200
+ ├── Runs/
201
+ ├── Projects/
202
+ ├── Domains/
203
+ ├── Playbooks/
204
+ ├── References/
205
+ ├── Templates/
206
+ └── Wiki/ # generated; safe to rebuild
207
+ ├── Entities/
208
+ ├── Concepts/
209
+ └── Synthesis/ # compatibility path for generated source indexes
210
+ ```
211
+
212
+ Everything else is outside the shared agent index, including `Journal/`, `Private/`, `Inbox/`, `Archive/`, `Side Projects/`, `Strategies/`, and `Backtests/`.
213
+
214
+ A Capture Note should cover one durable claim and uses the versioned v1
215
+ contract below. The opaque `id` stays stable if the file moves. Optional
216
+ `source_refs` are a flat list of durable provenance strings.
217
+
218
+ ```yaml
219
+ ---
220
+ schema_version: 1
221
+ id: mem-12345678-1234-4abc-8def-1234567890ab
222
+ type: decision
223
+ project: memory-lab
224
+ entity_type: app
225
+ entity_id: memory-lab
226
+ writer_agent: codex
227
+ status: active
228
+ # Optional on a successor note:
229
+ # supersedes: mem-00000000-0000-4000-8000-000000000000
230
+ created: 2026-07-26T00:00:00+00:00
231
+ source_refs:
232
+ - "issue:#53"
233
+ ---
234
+ ```
235
+
236
+ The shared parser, validator, and renderer govern MCP writes, ingest, and Wiki
237
+ compilation. A malformed v1 note fails before derived-state mutation. Existing
238
+ legacy active Capture Notes remain readable and are not rewritten or assigned
239
+ synthetic IDs.
240
+
241
+ The canonical lifecycle statuses are `active`, `superseded`, and `retracted`.
242
+ To replace a claim, append a new Capture Note with `supersedes` set to the
243
+ predecessor's stable ID; the predecessor file stays unchanged. The graph makes
244
+ the predecessor effectively `superseded`. To withdraw a claim without a
245
+ replacement, append a `retracted` note that supersedes the current head.
246
+ Lifecycle links must stay in the same entity scope and memory type. Dangling
247
+ links, self-links, cycles, and forks fail before SQLite or Wiki mutation.
248
+ Recall and Wiki source indexes expose only effective `active` heads. Superseded and
249
+ retracted notes remain in raw evidence, audit history, and the Wiki History
250
+ section. Rebuild derives the same lifecycle state from Markdown.
251
+
252
+ The vault defaults to:
253
+
254
+ ```text
255
+ ~/Library/Mobile Documents/iCloud~md~obsidian/Documents/
256
+ ```
257
+
258
+ Override it with `MEMORY_LAB_OBSIDIAN_DIR` for fixtures or another vault.
259
+
260
+ Obsidian refreshes Markdown changed by external tools, and iCloud handles device-to-device vault sync. Memory Lab therefore does not run a file watcher or bidirectional sync daemon.
261
+
262
+ ## Compile the Wiki Projection
263
+
264
+ Preview the deterministic projection without writing:
265
+
266
+ ```bash
267
+ memory-lab wiki compile
268
+ ```
269
+
270
+ Apply it and refresh the SQLite evidence index:
271
+
272
+ ```bash
273
+ memory-lab wiki compile --apply
274
+ memory-lab wiki lint
275
+ ```
276
+
277
+ The compiler never edits Capture Notes. It creates scope pages with Current and
278
+ History sections, deterministic source indexes of current claims, and
279
+ concept pages from explicit repo, workflow, tool, and ticket mentions. The
280
+ projection records concept occurrences, explicit scope membership, lifecycle
281
+ history, and source citations. It does not infer a typed relationship from
282
+ concepts in the same note or from retrieval similarity. Re-running compilation
283
+ is idempotent, removes only stale pages marked `generated_by: memory-lab-wiki`,
284
+ and refuses symlinked or unowned output paths.
285
+
286
+ ## Onboard a project
287
+
288
+ Run onboarding once from a Git repository:
289
+
290
+ ```bash
291
+ memory-lab onboard --repo /path/to/your/repo \
292
+ --title CardDex --alias cardex-template
293
+ ```
294
+
295
+ The command derives the canonical project ID from the `origin` remote (for example, `haru3613-carddex`), creates `Agent Knowledge/Projects/carddex/Overview.md` without overwriting an existing note, updates `~/.mem0/project_map.json`, and incrementally indexes the vault. Use `MEMORY_LAB_MEM0_PROJECT_MAP` to override the map path.
296
+
297
+ ## Promote curated knowledge
298
+
299
+ Promotion is explicit and dry-run by default:
300
+
301
+ ```bash
302
+ memory-lab promote --project haru3613-carddex --kind decision \
303
+ --title "Use source-native prices" --from-file /tmp/decision.md
304
+ ```
305
+
306
+ Review the rendered note, then repeat with `--apply`. The command writes a
307
+ dated APP note under the onboarded project's `Preferences/`, `Decisions/`,
308
+ `Lessons/`, or `References/` folder, refuses to overwrite an existing file, and
309
+ refreshes the derived SQLite index.
310
+
311
+ ## Ingest Obsidian evidence
312
+
313
+ Incrementally ingest new or changed Markdown notes:
314
+
315
+ ```bash
316
+ memory-lab ingest-obsidian
317
+ ```
318
+
319
+ Normal ingestion skips unchanged files and deliberately does not prune missing notes. A partial iCloud sync therefore cannot wipe previously indexed evidence.
320
+
321
+ When changing the trust boundary or intentionally rebuilding the disposable Obsidian corpus, use the explicit rebuild mode:
322
+
323
+ ```bash
324
+ memory-lab ingest-obsidian --rebuild
325
+ ```
326
+
327
+ Rebuild preflights every approved note before opening the replacement transaction, then replaces only `project_key='obsidian'` evidence. The memory layer is preserved: links to retained note paths are remapped to their new evidence rows, while provenance for removed paths is retained in memory metadata. If an existing corpus is populated but fewer approved notes are available than `MEMORY_LAB_OBSIDIAN_REBUILD_MIN_NOTES` (default `1`), the rebuild aborts before deleting anything.
328
+
329
+ Only `.md` files are imported. Allowlisted-root symlinks and nested paths that resolve outside `Agent Knowledge/` fail closed. Empty notes also fail before writes. Searchable text passes through secret redaction before FTS indexing, but credentials and private material still belong outside `Agent Knowledge/`.
330
+
331
+ ## Ingest Claude conversation evidence
332
+
333
+ ```bash
334
+ memory-lab ingest --all --incremental --index-entities --extract-candidates
335
+
336
+ memory-lab stats
337
+ ```
338
+
339
+ Claude ingestion is restricted to the corpora listed under `[projects]` in
340
+ `~/.config/memory-lab/config.toml`. An unconfigured install ingests nothing.
341
+
342
+ ## Legacy auto-memory import
343
+
344
+ This migration-only command imports selected one-fact Markdown files into the legacy memory tables. It is retained for rollback compatibility, not for new cross-agent knowledge; use `onboard` and `promote` for that.
345
+
346
+ Review a read-only plan first:
347
+
348
+ ```bash
349
+ memory-lab import-auto-memory \
350
+ --dir ~/.claude/projects/<project>/memory \
351
+ --project cardex-template \
352
+ --include feedback_example.md \
353
+ --include reference_example.md \
354
+ --dry-run
355
+ ```
356
+
357
+ Rerun the same command without `--dry-run` to write. `MEMORY.md` is always skipped. The importer accepts scalar `name`, `description`, `type`, and `originSessionId` fields, with `type` and `originSessionId` also allowed one level under `metadata`; folded or otherwise complex YAML values fail preflight. It maps supported Claude memory types into Memory Lab types, stores absolute source-path and content-hash provenance, skips exact duplicates, and supersedes a prior import when the same source changes. It never modifies source files or scans an entire directory automatically. When `MEMORY_LAB_REQUIRE_REVIEW=1`, a batch where one pending source update depends on another pending source's old content fails preflight; split that dependency into separately reviewed imports.
358
+
359
+ ## Search
360
+
361
+ ```bash
362
+ memory-lab search "Mission Control no auto-merge" \
363
+ --project mission-control --top-k 5 --debug
364
+
365
+ memory-lab search "設計決策" \
366
+ --project obsidian --top-k 5
367
+ ```
368
+
369
+ ASCII evidence uses SQLite FTS5/BM25. CJK terms use a scoped escaped substring fallback, with BM25 matches ranked ahead of fallback-only results. Every evidence result includes its source path.
370
+
371
+ An unscoped or Obsidian-scoped CLI search refreshes changed Markdown before querying. If refresh fails, it warns and searches the last valid index. MCP search follows the same lazy-refresh behavior when the requested evidence scope includes Obsidian.
372
+
373
+ ## MCP surface
374
+
375
+ Agents use this server for retrieval and append-only Agent Knowledge curation:
376
+
377
+ ```bash
378
+ memory-lab serve-mcp --agent claude-code
379
+ ```
380
+
381
+ - `memory_search(query=..., project="carddex")` searches legacy memory plus CardDex's scoped Obsidian evidence.
382
+ - `memory_search(query=..., user_id="harvey", agent_id="codex", app_id="haru3613-carddex", run_id=...)` searches the exact union of active entities.
383
+ - `memory_search(query=..., project="obsidian")` searches all approved Obsidian evidence.
384
+ - `memory_remember(project="carddex", kind="decision", title=..., content=..., source_refs=[...])` creates a new Markdown note without modifying existing notes.
385
+ - `memory_remember(entity_type="user", entity_id="harvey", kind="preference", title=..., content=..., source_refs=[...])` writes user-scoped knowledge.
386
+
387
+ Evidence is enabled by default. For onboarded projects, the server resolves the folder, canonical ID, and aliases from `Projects/<folder>/Overview.md`; pass `include_evidence=false` only when a caller explicitly wants legacy memories alone.
388
+
389
+ Search responses include a `query_id` and `index_status`; memory results retain
390
+ their integer `memory_id` and expose nullable `capture_id`. Remember responses
391
+ include the stable `capture_id`, primary entity, note path, SHA-256, indexed
392
+ evidence event ID, derived integer memory ID, and `indexed` status. Identical remember retries are
393
+ safe and return `status="existing"`; same-title requests with different content
394
+ still fail instead of overwriting the note.
395
+
396
+ After upgrading an older index, run one successful search or `ingest-obsidian` while the vault is available to backfill canonical IDs and aliases. Until then, an offline legacy index can route project evidence only by folder name.
397
+
398
+ Use `memory_remember` for explicit requests to remember something and for durable decisions, lessons, and references established during a task. Do not store transient status, speculation, or secrets. Existing notes remain immutable through MCP: update and delete tools are not exposed.
399
+
400
+ Agent hosts must enforce the start, running, and closeout behavior in the
401
+ [session lifecycle contract](docs/wiring/session-lifecycle.md); starting the MCP
402
+ process alone does not prove that an agent read or wrote memory.
403
+
404
+ Do not share one SQLite store across personal and company trust boundaries. Use a separate `--db` path for each boundary; see [`docs/wiring/store-isolation.md`](docs/wiring/store-isolation.md). Per-agent setup lives under [`docs/wiring/`](docs/wiring/).
405
+
406
+ ## Evaluate retrieval
407
+
408
+ ```bash
409
+ # evidence layer (raw notes)
410
+ memory-lab eval run --question-set baseline
411
+
412
+ # memory layer: each question asked in exact English, English paraphrase and
413
+ # Chinese, plus hard negatives that must return nothing
414
+ memory-lab eval run --question-set memory-v2
415
+ ```
416
+
417
+ The memory set reports recall@1/@k and MRR per phrasing, a hard-negative
418
+ false-positive rate, and the same two numbers for the *injected* set — what the
419
+ `UserPromptSubmit` hook would actually have shown an agent. Run it against a
420
+ copy of the store if you care about the query log: the eval itself never writes
421
+ to `query_log`, but nothing else about `--db` is read-only.
422
+
423
+ The injection gate keeps hits within `35%` of the top score and above an
424
+ absolute floor of `K * log10(active memories)`, disabled below 50 memories.
425
+ `K` defaults to `3.0`, calibrated against `eval/memory-v2.json`; override it with
426
+ `MEMORY_LAB_INJECT_SCORE_FLOOR_K` and re-run the memory eval to see the effect on
427
+ injected recall and the injected false-positive rate.
428
+
429
+ Generated SQLite databases and eval reports live under gitignored `data/`.
430
+
431
+ ## Read-only UI
432
+
433
+ The Nuxt 3 viewer under `ui/` browses memories, evidence, and stats. Its SQLite driver is read-only.
434
+
435
+ ```bash
436
+ cd ui
437
+ npm install
438
+ npm run dev
439
+ ```
440
+
441
+ It defaults to `../data/claude-memory-lab.sqlite`, which is the *legacy* store
442
+ location. The CLI may resolve a different one on a fresh install, so point the
443
+ viewer explicitly at whatever `memory-lab stats` reports:
444
+
445
+ ```bash
446
+ MEMORY_LAB_DB=/path/to/store.sqlite npm run dev
447
+ ```
448
+
449
+ Legacy review actions remain CLI-only for rollback/admin use.