claude_memory 0.12.0 → 0.12.1
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.
- checksums.yaml +4 -4
- data/.claude/memory.sqlite3 +0 -0
- data/.claude/rules/claude_memory.generated.md +39 -48
- data/.claude-plugin/marketplace.json +1 -1
- data/.claude-plugin/plugin.json +2 -4
- data/CHANGELOG.md +24 -0
- data/CLAUDE.md +2 -2
- data/README.md +11 -0
- data/docs/api_stability.md +7 -2
- data/docs/soak/audit_2026-06-03_agent-training-program.json +53 -0
- data/docs/soak/audit_2026-06-03_agentic.json +31 -0
- data/docs/soak/audit_2026-06-03_ai-software-architect.json +19 -0
- data/docs/soak/audit_2026-06-03_chaos_to_the_rescue.json +60 -0
- data/docs/soak/audit_2026-06-03_claude_memory.json +55 -0
- data/docs/soak/audit_2026-06-03_daily-vibe.json +59 -0
- data/docs/soak/audit_2026-06-03_minerva-sky.json +19 -0
- data/docs/soak/audit_2026-06-03_nowreading.dev.json +19 -0
- data/docs/soak/audit_2026-06-03_ups.dev.json +55 -0
- data/docs/soak/baseline_2026-06-03.md +145 -0
- data/lib/claude_memory/commands/checks/embeddings_check.rb +97 -0
- data/lib/claude_memory/commands/doctor_command.rb +1 -0
- data/lib/claude_memory/commands/registry.rb +1 -0
- data/lib/claude_memory/commands/setup_vectors_command.rb +182 -0
- data/lib/claude_memory/version.rb +1 -1
- data/lib/claude_memory.rb +2 -0
- metadata +13 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cec498c9aec388d1decdcb7ae05616fb414d7f026401248b6a051d051d238e39
|
|
4
|
+
data.tar.gz: 9a8b44aa97db10ead04a074f2619f08cdb74976dd22ce7843a5968bbbbda410e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22c84d179c6af89f06909604674794741739237edc5cdb11c18bd9ba06ae4f9334bf20a4d8e8057181d25a206419cf50b35fec392ec3cd7d5fb093ea0046ef0c
|
|
7
|
+
data.tar.gz: a138ae2049416a7ec21ecef3545115a8415a2d64618d8f3334a50e2b6d552b61a7056824f5ef968b78907cfbc6515e38f60a1feed75a4db8b94793736bf0826d
|
data/.claude/memory.sqlite3
CHANGED
|
Binary file
|
|
@@ -1,69 +1,60 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
This file is auto-generated by claude-memory.
|
|
3
3
|
Do not edit manually - changes will be overwritten.
|
|
4
|
-
Generated: 2026-06-
|
|
4
|
+
Generated: 2026-06-03T13:21:02Z
|
|
5
5
|
-->
|
|
6
6
|
|
|
7
7
|
# Project Memory
|
|
8
8
|
|
|
9
9
|
## Current Decisions
|
|
10
10
|
|
|
11
|
-
- MCP tool-call telemetry stores minimal columns (tool_name, duration_ms, result_count, scope, error_class) — deliberately no query_text or query_hash. YAGNI: hashes are write-only without the raw text, and raw text adds privacy concerns without clear value beyond existing shortcut tools (memory.decisions, memory.conventions).
|
|
12
|
-
- From QMD 2026-02-02 restudy: adopt Claude Code plugin format, MCP structured content pattern, MCP query guide prompt, inline status checks. Carry forward sqlite-vec, RRF, docids, smart expansion from 2026-01-26. Reject custom fine-tuned models, LLM reranking, YAML collections.
|
|
13
|
-
- From claude-supermemory study: adopt SessionStart hook context injection (hookSpecificOutput.additionalContext), tool-specific observation compression, and relative time formatting. Reject cloud storage dependency and no-test approach.
|
|
11
|
+
- MCP tool-call telemetry stores minimal columns (tool_name, duration_ms, result_count, scope, error_class) — deliberately no query_text or query_hash. YAGNI: hashes are write-only without the raw text, and raw text adds privacy concerns without clear value beyond existing shortcut tools (memory.decisions, memory.conventions). — to avoid storing query hashes that are write-only without the raw text.
|
|
12
|
+
- From QMD 2026-02-02 restudy: adopt Claude Code plugin format, MCP structured content pattern, MCP query guide prompt, inline status checks. Carry forward sqlite-vec, RRF, docids, smart expansion from 2026-01-26. Reject custom fine-tuned models, LLM reranking, YAML collections. — to align with our pure-Ruby/SQLite constraints (no GGUF, no LLM-side fine-tuning).
|
|
13
|
+
- From claude-supermemory study: adopt SessionStart hook context injection (hookSpecificOutput.additionalContext), tool-specific observation compression, and relative time formatting. Reject cloud storage dependency and no-test approach. — to avoid cloud-storage lock-in and no-test fragility identified in the study.
|
|
14
14
|
|
|
15
15
|
## Conventions
|
|
16
16
|
|
|
17
|
-
- A/B testing methodology for memory plugin evaluation — How to test with/without memory using claude CLI — --plugin-dir doesn't work with --bare, use --mcp-config instead — To A/B test memory's impact on Claude Code responses: (imported from project auto-memory; see source file for full reasoning)
|
|
18
|
-
- do...end blocks over braces when args repeat or block is non-trivial — Block syntax preference for multi-argument or multi-expression blocks — When a block call has repeated argument names, multiple expressions, or reads awkwardly on one line, use `do...end` form rather than `{ }`. One-liners with simple single-expression bodies and short argument lists are fine with braces. (imported from project auto-memory; see source file for full reasoning)
|
|
19
|
-
- Always commit .claude/memory.sqlite3 — Per user direction (2026-05-21), .claude/memory.sqlite3 should be staged and committed alongside any change that updates project memory — even though it's a binary SQLite DB with WAL artifacts. — Always include `.claude/memory.sqlite3` in commits that touch project memory or knowledge. (imported from project auto-memory; see source file for full reasoning)
|
|
17
|
+
- A/B testing methodology for memory plugin evaluation — How to test with/without memory using claude CLI — --plugin-dir doesn't work with --bare, use --mcp-config instead — To A/B test memory's impact on Claude Code responses: (imported from project auto-memory; see source file for full reasoning) — to enable head-to-head measurement of memory's impact on Claude Code responses.
|
|
18
|
+
- do...end blocks over braces when args repeat or block is non-trivial — Block syntax preference for multi-argument or multi-expression blocks — When a block call has repeated argument names, multiple expressions, or reads awkwardly on one line, use `do...end` form rather than `{ }`. One-liners with simple single-expression bodies and short argument lists are fine with braces. (imported from project auto-memory; see source file for full reasoning) — to keep multi-line blocks readable and avoid brace/multi-expression awkwardness.
|
|
19
|
+
- Always commit .claude/memory.sqlite3 — Per user direction (2026-05-21), .claude/memory.sqlite3 should be staged and committed alongside any change that updates project memory — even though it's a binary SQLite DB with WAL artifacts. — Always include `.claude/memory.sqlite3` in commits that touch project memory or knowledge. (imported from project auto-memory; see source file for full reasoning) — to ensure project memory is reproducible across collaborators.
|
|
20
20
|
- Commit workflow preferences — How the user prefers commits to be structured and when to make them — Wait for the user to ask for commits — don't commit proactively. When asked, group changes into logical atomic commits: (imported from project auto-memory; see source file for full reasoning)
|
|
21
|
-
- Data-driven analysis before design changes — User expects thorough multi-project data surveys and critical questioning of assumptions before committing to architectural changes — When proposing design changes (especially to schemas, vocabularies, or policies), gather real usage data first and present a critical analysis before implementing. (imported from project auto-memory; see source file for full reasoning)
|
|
22
|
-
- Fix hallucination triggers at the source, not via repeated reject churn — When the distiller repeatedly produces the same wrong fact, trace it to the CLAUDE.md / docs example text; fixing the source stops re-appearance — When the dashboard's Conflicts tab accumulates clusters of the same kind of bad fact (e.g. many `uses_database` contradictions against `sqlite`), the root cause is almost always **example text in documentation** that the distiller is interpreting as a literal claim about the current repo. Single-value predicates (`uses_database`, `deployment_platform`, `auth_method`) are especially vulnerable becau... (imported from project auto-memory; see source file for full reasoning)
|
|
23
|
-
- Hooks run the installed gem, not the working copy — always `rake install` after editing hook/MCP code — .claude/settings.json hooks invoke `claude-memory` via PATH, so changes on a branch only take effect after `bundle exec rake install` — `.claude/settings.json` hooks call bare `claude-memory hook ingest` / `claude-memory hook context` / etc. That resolves via PATH to the installed gem, not the working-copy `./exe/claude-memory`. After editing any hook/MCP/distiller code on a branch, the change does NOT reach Claude Code until `bundle exec rake install` rebuilds and reinstalls the gem (which overwrites the prior install at the same ... (imported from project auto-memory; see source file for full reasoning)
|
|
24
|
-
- No extra API costs for features — User strongly prefers using Claude Code itself (skills, context hooks) over separate API calls that cost extra money — Do not add features that require separate Anthropic API calls (e.g., via anthropic-rb gem) when Claude Code itself can perform the same task. Use skills, context hook injection, and MCP tools to leverage the existing Claude Code session instead. (imported from project auto-memory; see source file for full reasoning)
|
|
25
|
-
- Quality review update cycle — Keep quality_review.md current as items are resolved — don't let it drift — When completing quality review items, update `docs/quality_review.md` immediately: (imported from project auto-memory; see source file for full reasoning)
|
|
21
|
+
- Data-driven analysis before design changes — User expects thorough multi-project data surveys and critical questioning of assumptions before committing to architectural changes — When proposing design changes (especially to schemas, vocabularies, or policies), gather real usage data first and present a critical analysis before implementing. (imported from project auto-memory; see source file for full reasoning) — to avoid premature architectural commitments before real usage data is in hand.
|
|
22
|
+
- Fix hallucination triggers at the source, not via repeated reject churn — When the distiller repeatedly produces the same wrong fact, trace it to the CLAUDE.md / docs example text; fixing the source stops re-appearance — When the dashboard's Conflicts tab accumulates clusters of the same kind of bad fact (e.g. many `uses_database` contradictions against `sqlite`), the root cause is almost always **example text in documentation** that the distiller is interpreting as a literal claim about the current repo. Single-value predicates (`uses_database`, `deployment_platform`, `auth_method`) are especially vulnerable becau... (imported from project auto-memory; see source file for full reasoning) — because reject-only is treating symptoms; the root cause is doc/example text the distiller mistakes for project claims.
|
|
23
|
+
- Hooks run the installed gem, not the working copy — always `rake install` after editing hook/MCP code — .claude/settings.json hooks invoke `claude-memory` via PATH, so changes on a branch only take effect after `bundle exec rake install` — `.claude/settings.json` hooks call bare `claude-memory hook ingest` / `claude-memory hook context` / etc. That resolves via PATH to the installed gem, not the working-copy `./exe/claude-memory`. After editing any hook/MCP/distiller code on a branch, the change does NOT reach Claude Code until `bundle exec rake install` rebuilds and reinstalls the gem (which overwrites the prior install at the same ... (imported from project auto-memory; see source file for full reasoning) — to ensure code changes reach the production hooks, which invoke the installed gem via PATH.
|
|
24
|
+
- No extra API costs for features — User strongly prefers using Claude Code itself (skills, context hooks) over separate API calls that cost extra money — Do not add features that require separate Anthropic API calls (e.g., via anthropic-rb gem) when Claude Code itself can perform the same task. Use skills, context hook injection, and MCP tools to leverage the existing Claude Code session instead. (imported from project auto-memory; see source file for full reasoning) — to avoid hidden ongoing spend that bypasses the Claude Code session's existing budget.
|
|
25
|
+
- Quality review update cycle — Keep quality_review.md current as items are resolved — don't let it drift — When completing quality review items, update `docs/quality_review.md` immediately: (imported from project auto-memory; see source file for full reasoning) — to prevent quality_review.md from drifting out of date.
|
|
26
26
|
- Refactoring approach preferences — How to approach god object extraction and structural refactoring in this codebase — Use module inclusion (not class extraction) when breaking up god objects. Include modules directly into the existing class so the public API is unchanged and zero tests need modification. This was validated three times:
|
|
27
|
-
- Round-trip migration specs cover each prior release boundary — For pre-release prep, write end-to-end migration specs from every distinct schema boundary back through ~3 prior releases — Before cutting a release that includes migrations, add round-trip specs that fixture an older DB at each distinct prior release's schema version, open via `SQLiteStore.new`, and assert the full upgrade path: schema_info advancement, data preservation across entities/facts/content_items/provenance, additive table/column creation, predicate-rewrite effects where applicable, and idempotency on re-open... (imported from project auto-memory; see source file for full reasoning)
|
|
27
|
+
- Round-trip migration specs cover each prior release boundary — For pre-release prep, write end-to-end migration specs from every distinct schema boundary back through ~3 prior releases — Before cutting a release that includes migrations, add round-trip specs that fixture an older DB at each distinct prior release's schema version, open via `SQLiteStore.new`, and assert the full upgrade path: schema_info advancement, data preservation across entities/facts/content_items/provenance, additive table/column creation, predicate-rewrite effects where applicable, and idempotency on re-open... (imported from project auto-memory; see source file for full reasoning) — to ensure migrations remain forward-compatible across release boundaries.
|
|
28
28
|
- Codify behavioral contracts in tests, not just comments — When code has a deliberate scope limitation (one-shot, advisory-only, intentionally non-idempotent), write a test that fails if someone "fixes" it into being more general — When code has a deliberate scope limitation — a one-shot data migration, an advisory-only field, a method intentionally not idempotent for new inputs — write a test that exercises a scenario which would *break* if someone tried to make it more general. (imported from project auto-memory; see source file for full reasoning)
|
|
29
|
-
- Treat UX gaps as architecture smells — user inspection/debugging questions expose god classes and missing abstractions — When users ask "can I see/debug/act on X in the dashboard?", the answer is almost always "we need a new class or route, not a new button" — Across three architectural reviews in the 2026-04-17 → 20 session, every concrete UX gap the user identified traced back to a structural issue the code already had, not a frontend-only fix. Treating critique as a forcing function for refactoring produced cleaner results than either extracting preemptively (premature) or patching only the surface (symptom). (imported from project auto-memory; see source file for full reasoning)
|
|
30
|
-
- "database disk image is malformed" from FTS5 `ORDER BY rank` after sqlite3 .recover — sqlite3 .recover restores rows but can leave contentless FTS5 auxiliary indexes in a state where basic MATCH works but ORDER BY rank throws "malformed"; fix is `claude-memory compact` to rebuild the FTS index — A DB recovered via `sqlite3 corrupt.db .recover > dump.sql && sqlite3 fresh.db < dump.sql` can end up with an FTS5 index that's *partially* functional: (imported from project auto-memory; see source file for full reasoning)
|
|
31
|
-
- `rake install` uses `git ls-files`; untracked files silently disappear from the gem — Running `bundle exec rake install` before staging new files produces a gem missing those files, causing LoadError in hooks and MCP server — The claude_memory gemspec builds its file list via `IO.popen(%w[git ls-files -z], ...)` (claude_memory.gemspec:24). Any file that hasn't been `git add`ed at build time is **invisible to the gem** even though it exists on disk. The local working copy keeps running fine (dashboard server uses `./exe/claude-memory` against the repo directly), but the installed gem at `~/.gem/ruby/*/gems/claude_memory-... (imported from project auto-memory; see source file for full reasoning)
|
|
32
|
-
- Distiller scope_hint is advisory, not a routing signal — NullDistiller emits scope_hint: "global" for text matching GLOBAL_SCOPE_PATTERNS, but the resolver never routes writes between stores — scope_hint must not override fact.scope — `Distill::NullDistiller#global_scope_signal?` matches text like "always" / "my preference" / "in all projects" and stamps `scope_hint: "global"` on every fact extracted from that text. The hint is advisory metadata for downstream promotion decisions. It is NOT a routing signal — the resolver writes to whichever `SQLiteStore` was injected into it (always the project DB in the normal ingest path), re... (imported from project auto-memory; see source file for full reasoning)
|
|
33
|
-
- Sequel DB reads must use the extralite adapter — Opening a SQLite DB for ad-hoc reads requires the extralite adapter URI; Sequel.sqlite silently depends on an ungem'd sqlite3 — Never use `Sequel.sqlite(db_path)` or `Sequel.sqlite(db_path, readonly: true)` in this codebase. The gemspec lists only `extralite (~> 2.14)` — it does **not** depend on the `sqlite3` gem. `Sequel.sqlite` routes through Sequel's `sqlite` adapter which requires `gem "sqlite3"` and will raise `Sequel::AdapterNotFound: LoadError: cannot load such file -- sqlite3` at runtime. (imported from project auto-memory; see source file for full reasoning)
|
|
34
|
-
- Never `git checkout --` an active SQLite DB with WAL mode — Using `git checkout --` on .claude/memory.sqlite3 while readers/writers are open corrupts the DB via WAL/main file mismatch — Never run `git checkout -- .claude/memory.sqlite3` (or any SQLite DB in WAL mode) while any process has it open. Git replaces only the main DB file, leaving the WAL/SHM sidecar files referencing pages that no longer exist in the replaced file. Next read → "Extralite::Error: database disk image is malformed" and integrity_check shows btree errors across multiple trees. (imported from project auto-memory; see source file for full reasoning)
|
|
35
|
-
- SQLiteStore silently creates in-memory DB for relative paths — `SQLiteStore.new('.claude/memory.sqlite3')` with a relative path opens an empty in-memory DB, not the file — always pass absolute paths in tests/probes — `SQLiteStore.new(path)` builds a Sequel URI as `extralite:#{path}`. With a relative path like `.claude/memory.sqlite3`, the resulting URI `extralite:.claude/memory.sqlite3` is parsed with an empty database component, so Extralite opens an in-memory database. Schema migrations run against the in-memory DB (so `schema_version` reports the current version), but ALL queries return 0 rows and the real f... (imported from project auto-memory; see source file for full reasoning)
|
|
36
|
-
- Two tool_calls tables exist — don't conflate them — tool_calls (v3) stores transcript-observed Claude Code tool usage; mcp_tool_calls (v13) stores MCP server telemetry — There are **two** tables with similar names serving different purposes: (imported from project auto-memory; see source file for full reasoning)
|
|
37
|
-
- Distiller hallucination from CLAUDE.md example text — The scope-system example in CLAUDE.md causes recurring false fact extraction — reject + re-ingest creates rejection churn — CLAUDE.md contains a scope-system explanation with example text: (imported from project auto-memory; see source file for full reasoning)
|
|
38
|
-
- PredicatePolicy is the single source of truth for predicate vocabulary — All predicate knowledge (vocabulary, cardinality, sections, synonyms, LLM guidance) derives from PredicatePolicy — never hardcode predicate names elsewhere — As of 0.9.0, `PredicatePolicy` in `lib/claude_memory/resolve/predicate_policy.rb` is the authoritative source for all predicate-related behavior. This was a deliberate consolidation after finding the same predicate list duplicated in 4 files that drifted independently. (imported from project auto-memory; see source file for full reasoning)
|
|
29
|
+
- Treat UX gaps as architecture smells — user inspection/debugging questions expose god classes and missing abstractions — When users ask "can I see/debug/act on X in the dashboard?", the answer is almost always "we need a new class or route, not a new button" — Across three architectural reviews in the 2026-04-17 → 20 session, every concrete UX gap the user identified traced back to a structural issue the code already had, not a frontend-only fix. Treating critique as a forcing function for refactoring produced cleaner results than either extracting preemptively (premature) or patching only the surface (symptom). (imported from project auto-memory; see source file for full reasoning) — because frontend patches usually mask structural debt that surfaces later.
|
|
30
|
+
- "database disk image is malformed" from FTS5 `ORDER BY rank` after sqlite3 .recover — sqlite3 .recover restores rows but can leave contentless FTS5 auxiliary indexes in a state where basic MATCH works but ORDER BY rank throws "malformed"; fix is `claude-memory compact` to rebuild the FTS index — A DB recovered via `sqlite3 corrupt.db .recover > dump.sql && sqlite3 fresh.db < dump.sql` can end up with an FTS5 index that's *partially* functional: (imported from project auto-memory; see source file for full reasoning) — fix is claude-memory compact to rebuild the FTS index without doing another .recover.
|
|
31
|
+
- `rake install` uses `git ls-files`; untracked files silently disappear from the gem — Running `bundle exec rake install` before staging new files produces a gem missing those files, causing LoadError in hooks and MCP server — The claude_memory gemspec builds its file list via `IO.popen(%w[git ls-files -z], ...)` (claude_memory.gemspec:24). Any file that hasn't been `git add`ed at build time is **invisible to the gem** even though it exists on disk. The local working copy keeps running fine (dashboard server uses `./exe/claude-memory` against the repo directly), but the installed gem at `~/.gem/ruby/*/gems/claude_memory-... (imported from project auto-memory; see source file for full reasoning) — to ensure new files reach the installed gem (the gemspec uses git ls-files for the manifest).
|
|
32
|
+
- Distiller scope_hint is advisory, not a routing signal — NullDistiller emits scope_hint: "global" for text matching GLOBAL_SCOPE_PATTERNS, but the resolver never routes writes between stores — scope_hint must not override fact.scope — `Distill::NullDistiller#global_scope_signal?` matches text like "always" / "my preference" / "in all projects" and stamps `scope_hint: "global"` on every fact extracted from that text. The hint is advisory metadata for downstream promotion decisions. It is NOT a routing signal — the resolver writes to whichever `SQLiteStore` was injected into it (always the project DB in the normal ingest path), re... (imported from project auto-memory; see source file for full reasoning) — to prevent scope drift between resolver-determined store and distiller-stamped hint.
|
|
33
|
+
- Sequel DB reads must use the extralite adapter — Opening a SQLite DB for ad-hoc reads requires the extralite adapter URI; Sequel.sqlite silently depends on an ungem'd sqlite3 — Never use `Sequel.sqlite(db_path)` or `Sequel.sqlite(db_path, readonly: true)` in this codebase. The gemspec lists only `extralite (~> 2.14)` — it does **not** depend on the `sqlite3` gem. `Sequel.sqlite` routes through Sequel's `sqlite` adapter which requires `gem "sqlite3"` and will raise `Sequel::AdapterNotFound: LoadError: cannot load such file -- sqlite3` at runtime. (imported from project auto-memory; see source file for full reasoning) — to avoid Sequel::AdapterNotFound at runtime (this gem doesn't depend on the sqlite3 adapter).
|
|
34
|
+
- Never `git checkout --` an active SQLite DB with WAL mode — Using `git checkout --` on .claude/memory.sqlite3 while readers/writers are open corrupts the DB via WAL/main file mismatch — Never run `git checkout -- .claude/memory.sqlite3` (or any SQLite DB in WAL mode) while any process has it open. Git replaces only the main DB file, leaving the WAL/SHM sidecar files referencing pages that no longer exist in the replaced file. Next read → "Extralite::Error: database disk image is malformed" and integrity_check shows btree errors across multiple trees. (imported from project auto-memory; see source file for full reasoning) — to avoid WAL/main file mismatch corruption.
|
|
35
|
+
- SQLiteStore silently creates in-memory DB for relative paths — `SQLiteStore.new('.claude/memory.sqlite3')` with a relative path opens an empty in-memory DB, not the file — always pass absolute paths in tests/probes — `SQLiteStore.new(path)` builds a Sequel URI as `extralite:#{path}`. With a relative path like `.claude/memory.sqlite3`, the resulting URI `extralite:.claude/memory.sqlite3` is parsed with an empty database component, so Extralite opens an in-memory database. Schema migrations run against the in-memory DB (so `schema_version` reports the current version), but ALL queries return 0 rows and the real f... (imported from project auto-memory; see source file for full reasoning) — to ensure SQLiteStore opens the real file rather than a silent in-memory shadow.
|
|
36
|
+
- Two tool_calls tables exist — don't conflate them — tool_calls (v3) stores transcript-observed Claude Code tool usage; mcp_tool_calls (v13) stores MCP server telemetry — There are **two** tables with similar names serving different purposes: (imported from project auto-memory; see source file for full reasoning) — to avoid joining unrelated rows from disjoint telemetry tables.
|
|
37
|
+
- Distiller hallucination from CLAUDE.md example text — The scope-system example in CLAUDE.md causes recurring false fact extraction — reject + re-ingest creates rejection churn — CLAUDE.md contains a scope-system explanation with example text: (imported from project auto-memory; see source file for full reasoning) — to prevent re-extraction churn from documentation example text that the distiller takes literally.
|
|
38
|
+
- PredicatePolicy is the single source of truth for predicate vocabulary — All predicate knowledge (vocabulary, cardinality, sections, synonyms, LLM guidance) derives from PredicatePolicy — never hardcode predicate names elsewhere — As of 0.9.0, `PredicatePolicy` in `lib/claude_memory/resolve/predicate_policy.rb` is the authoritative source for all predicate-related behavior. This was a deliberate consolidation after finding the same predicate list duplicated in 4 files that drifted independently. (imported from project auto-memory; see source file for full reasoning) — to avoid divergent predicate lists across files that drifted independently before consolidation.
|
|
39
39
|
- Hook-telemetry features need a manual hook trigger to verify in production, not just specs — `bundle exec rake install` AND fire a real hook AND check `sqlite3 ... json_extract(detail_json, '$.<field>')`, because specs assert against working-tree code but `.claude/settings.json` hooks invoke the installed gem via PATH so the asserted field can be silently absent in production. Hit on 2026-04-30 shipping #47 token-budget telemetry: 156 specs green but `context_tokens` was missing from 24h of real activity_events.
|
|
40
|
-
- When verifying any new field on activity_events.detail_json, the canonical smoke test is: `echo '{"hook_event_name":"SessionStart","session_id":"smoketest","source":"startup","cwd":"$(pwd)"}' | claude-memory hook context` then inspect via `sqlite3 .claude/memory.sqlite3 "SELECT json_extract(detail_json, '$.<field>') FROM activity_events WHERE event_type='hook_context' ORDER BY id DESC LIMIT 1"`. If null after rake install, the installed gem code hasn't picked up the change.
|
|
40
|
+
- When verifying any new field on activity_events.detail_json, the canonical smoke test is: `echo '{"hook_event_name":"SessionStart","session_id":"smoketest","source":"startup","cwd":"$(pwd)"}' | claude-memory hook context` then inspect via `sqlite3 .claude/memory.sqlite3 "SELECT json_extract(detail_json, '$.<field>') FROM activity_events WHERE event_type='hook_context' ORDER BY id DESC LIMIT 1"`. If null after rake install, the installed gem code hasn't picked up the change. — to ensure the installed gem actually picks up new detail_json fields.
|
|
41
41
|
- Treat UX gaps as architecture smells: when a user asks "can I see/debug/act on X in the dashboard?" the answer is almost always a missing class or route, not a new button. Every UX critique in this project's dashboard work traced to a structural gap — god-class growth, four drifting fact serializers, scope_hint as silent scope override, no fact detail endpoint. Pattern: the surface question is usually a router into the architecture. Before reaching for frontend fixes, ask "what server-side data shape would make this easy?" — if that shape doesn't exist cleanly, treat it as the real work. Commit refactor separately from feature it enables ([Refactor]/[Feature]/[Fix] prefixes) so the critique→structural fix→UX fix chain is visible in git log.
|
|
42
42
|
- Four-surface staleness: after any change that touches UI + backend + plugin-launched binaries, refresh all four or the change looks broken. (1) bundle exec rake install so the installed gem catches up (hooks + MCP launched by Claude Code run from PATH). (2) Ctrl-C and re-run ./exe/claude-memory dashboard — server is long-lived Ruby, no live-reload. (3) /mcp reconnect in Claude Code so the MCP subprocess respawns. (4) Hard-refresh browser (Cmd-Shift-R) so cached index.html JS reloads. Skipping any produces confusing "my fix doesn't work." rspec green does NOT mean end-to-end works; before declaring UI-affecting changes done, curl the endpoint and verify shape matches frontend expectation. curl alt-port dashboard (--port 3388 --no-open in background) is fastest smoke test without disturbing user's running dashboard.
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
- Version must be updated in three places: lib/claude_memory/version.rb, .claude-plugin/plugin.json, .claude-plugin/marketplace.json. Runtime code uses ClaudeMemory::VERSION dynamically.
|
|
59
|
-
- Use module inclusion (not class extraction) to break up god objects — preserves public API so zero tests need modification
|
|
60
|
-
- Configuration class has instance methods only — use Configuration.new.global_db_path, not Configuration.global_db_path. Stub with instance_double + allow(Configuration).to receive(:new).and_return(config)
|
|
61
|
-
- OperationTracker.reset_stuck_operations only resets operations older than 24 hours (STALE_THRESHOLD_SECONDS). Tests must backdate started_at to trigger resets.
|
|
62
|
-
- SCHEMA_VERSION constant lives in Store::SchemaManager module but is accessible as SQLiteStore::SCHEMA_VERSION via Ruby include-based constant lookup
|
|
63
|
-
- MCP tools return dual content (text summary) + structuredContent (JSON) via TextSummary module and Server#handle_tools_call. Compact mode (compact: true) omits receipts for ~60% smaller responses.
|
|
64
|
-
- ContentSanitizer strips system-reminder, local-command-caveat, command-message, command-name, command-args tags in addition to private/no-memory/secret/claude-memory-context.
|
|
65
|
-
- Core::RelativeTime module provides progressive time formatting: just now → Xm ago → Xh ago → Xd ago → YYYY-MM-DD. Used in ResponseFormatter for *_ago fields.
|
|
66
|
-
- MCP server registers memory_guide prompt via prompts/list and prompts/get endpoints. QueryGuide module holds prompt content.
|
|
43
|
+
- MCP tool-call telemetry is recorded via MCP::Telemetry wrapping Server#handle_tools_call. Writes to mcp_tool_calls table in the project DB. Swallows DB errors so telemetry never breaks a real tool response. Viewable via 'claude-memory stats --tools [--since DAYS]'. — to ensure telemetry never breaks a real tool response (DB errors are swallowed).
|
|
44
|
+
- mcp_tool_calls retention is 90 days, enforced by Sweep::Maintenance#prune_old_mcp_tool_calls wired into Sweeper#run!. Configurable via mcp_tool_call_retention_days in Maintenance DEFAULT_CONFIG. — long enough to support quarterly tool-usage retrospectives without unbounded DB growth.
|
|
45
|
+
- CLAUDE_CONFIG_DIR env var overrides the default ~/.claude location for Configuration#global_db_path. Access via Configuration#claude_config_dir. Additive, backwards compatible. — to support test isolation and air-gapped installs that don't touch ~/.claude.
|
|
46
|
+
- Registry::COMMANDS stores {class:, description:} entries as the single source of truth for command name, class reference, and shell-completion description. Class constants stored directly (no const_get). Registry.descriptions feeds CompletionCommand; adding a new command requires updating only this hash. — to ensure adding a command requires only this hash update (no const_get, no description duplication).
|
|
47
|
+
- EXPECTED_HOOKS constant must stay in sync with events in HooksConfigurator#build_hooks_config. Adding a new hook event without updating EXPECTED_HOOKS causes false doctor warnings. — without this sync the doctor reports false hook-mismatch warnings.
|
|
48
|
+
- Tests using --db for hook context only set the project DB path. StoreManager still connects to the real global DB. Must stub Configuration to return a temp global path for isolation. — to ensure test isolation from the user's real global DB.
|
|
49
|
+
- Version must be updated in three places: lib/claude_memory/version.rb, .claude-plugin/plugin.json, .claude-plugin/marketplace.json. Runtime code uses ClaudeMemory::VERSION dynamically. — to ensure plugin/marketplace metadata matches the gem version on release.
|
|
50
|
+
- Use module inclusion (not class extraction) to break up god objects — preserves public API so zero tests need modification — to avoid breaking the public API and forcing test updates during god-object cleanup.
|
|
51
|
+
- Configuration class has instance methods only — use Configuration.new.global_db_path, not Configuration.global_db_path. Stub with instance_double + allow(Configuration).to receive(:new).and_return(config) — to make Configuration stubbable in tests via instance_double.
|
|
52
|
+
- OperationTracker.reset_stuck_operations only resets operations older than 24 hours (STALE_THRESHOLD_SECONDS). Tests must backdate started_at to trigger resets. — to prevent the reset from clobbering operations still legitimately in flight.
|
|
53
|
+
- SCHEMA_VERSION constant lives in Store::SchemaManager module but is accessible as SQLiteStore::SCHEMA_VERSION via Ruby include-based constant lookup — accessible via include because Ruby's constant lookup walks the inclusion chain.
|
|
54
|
+
- MCP tools return dual content (text summary) + structuredContent (JSON) via TextSummary module and Server#handle_tools_call. Compact mode (compact: true) omits receipts for ~60% smaller responses. — so that compact-mode callers pay ~60% fewer tokens per response.
|
|
55
|
+
- ContentSanitizer strips system-reminder, local-command-caveat, command-message, command-name, command-args tags in addition to private/no-memory/secret/claude-memory-context. — to prevent harness-internal tags from being ingested as user content.
|
|
56
|
+
- Core::RelativeTime module provides progressive time formatting: just now → Xm ago → Xh ago → Xd ago → YYYY-MM-DD. Used in ResponseFormatter for *_ago fields. — to make stale-fact warnings legible across both recent and old timestamps.
|
|
57
|
+
- MCP server registers memory_guide prompt via prompts/list and prompts/get endpoints. QueryGuide module holds prompt content. — to ensure memory_guide is discoverable via the standard MCP prompt registry.
|
|
67
58
|
|
|
68
59
|
## Technical Constraints
|
|
69
60
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"plugins": [
|
|
8
8
|
{
|
|
9
9
|
"name": "claude-memory",
|
|
10
|
-
"version": "0.12.
|
|
10
|
+
"version": "0.12.1",
|
|
11
11
|
"source": "./",
|
|
12
12
|
"description": "Long-term memory for Claude Code. Recalls architecture, conventions, and decisions across sessions — so Claude explains your codebase without file traversal, follows your patterns, and never re-asks what it already learned.",
|
|
13
13
|
"repository": "https://github.com/codenamev/claude_memory"
|
data/.claude-plugin/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-memory",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Long-term memory for Claude Code. Recalls architecture, conventions, and decisions across sessions — so Claude explains your codebase without file traversal, follows your patterns, and never re-asks what it already learned.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Valentino Stoll",
|
|
@@ -16,7 +16,5 @@
|
|
|
16
16
|
"args": []
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
|
-
"
|
|
20
|
-
"commands": "./commands/",
|
|
21
|
-
"outputStyles": "./output-styles/"
|
|
19
|
+
"commands": "./commands/"
|
|
22
20
|
}
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.12.1] - 2026-06-05
|
|
8
|
+
|
|
9
|
+
Theme: **Upgrade-experience patches surfaced by the 0.12.0 soak.** Four small but high-impact fixes — all uncovered by one user upgrading a single project — closing visibility gaps in the doctor and the plugin manifest. No schema changes, no breaking changes.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **`claude-memory setup-vectors` command** — the documented opt-in path for end users who want vector recall via the BAAI/bge-small-en-v1.5 model. fastembed remains a dev/test gem dependency by design (the default install stays light); this command verifies the chosen provider is loadable (gracefully prompts to `gem install fastembed` if not), writes `CLAUDE_MEMORY_EMBEDDING_PROVIDER` (and optional `CLAUDE_MEMORY_EMBEDDING_MODEL`) to the project's `.claude/settings.json` env block — the same mechanism Claude Code uses for OTel — and re-indexes existing facts via the existing `IndexCommand` (skip with `--no-reindex`). Supports `--status` for current config and `--dry-run` for inspection. Preserves unrelated settings.json keys.
|
|
14
|
+
- **`Checks::EmbeddingsCheck`** in `claude-memory doctor` — surfaces the active embedding provider name and dimensions, hints to set `CLAUDE_MEMORY_EMBEDDING_PROVIDER=fastembed` when on tfidf default and fastembed is loadable, and reports dimension mismatches between stored vectors and the current provider. Closes the visibility gap where a user could see `sqlite-vec available ✓` while silently running on tfidf without knowing.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **`plugin.json` declared `skills: "./skills/"` and `outputStyles: "./output-styles/"` pointing at non-existent directories.** Per Claude Code's plugin reference, `distill-transcripts.md` is correctly a flat *command* (not a skill); both forms register as `/<name>` slash commands. Dead keys removed. Plugin spec rewritten as deletion-safe ("every directory key in plugin.json points at an existing directory") so this can't regress.
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
- **README "Upgrading" section** now documents the marketplace-refresh + `/reload-plugins` flow explicitly. After `/plugin marketplace update <name>` users must run `/reload-plugins` or restart Claude Code for new slash commands to appear — this bit one user upgrading to 0.12.0 looking for `/distill-transcripts`. Includes `/audit-memory` and `/distill-transcripts` as named examples.
|
|
23
|
+
|
|
24
|
+
### Upgrade Notes
|
|
25
|
+
|
|
26
|
+
- No DB migrations. Schema stays at v18.
|
|
27
|
+
- After `gem update claude_memory`, run `/plugin marketplace update claude-memory && /reload-plugins` (or restart Claude Code) to see the new `/distill-transcripts` and `/audit-memory` slash commands.
|
|
28
|
+
- Existing fact bases continue to use whatever embedding provider they were indexed under. To opt into fastembed, run `claude-memory setup-vectors` — it handles provider switching + re-index in one step.
|
|
29
|
+
- `claude-memory doctor` will now emit a warning on tfidf default with fastembed loadable. This is informational, not an error; the system continues to function on tfidf.
|
|
30
|
+
|
|
7
31
|
## [0.12.0] - 2026-05-29
|
|
8
32
|
|
|
9
33
|
Theme: **Release Discipline + Observability + Self-Audit** — the infrastructure that makes a 1.0 semver promise defensible. This release locks down the public API surface, adds the observability primitives (OTel ingestion, dashboard Telemetry) and the self-audit toolkit (`claude-memory audit`) that serve the visibility pillar, and ships the negative-fact harm benchmark + staleness guard that make the long-horizon-quality claim measurable rather than aspirational.
|
data/CLAUDE.md
CHANGED
|
@@ -167,7 +167,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
167
167
|
- Each command is a separate class (HelpCommand, DoctorCommand, etc.)
|
|
168
168
|
- All commands inherit from BaseCommand
|
|
169
169
|
- Dependency injection for I/O (stdout, stderr, stdin)
|
|
170
|
-
-
|
|
170
|
+
- 38 commands total, each focused on single responsibility
|
|
171
171
|
|
|
172
172
|
- **`Configuration`**: Centralized ENV access (`configuration.rb`)
|
|
173
173
|
- Single source of truth for paths and environment variables
|
|
@@ -339,7 +339,7 @@ Also update `SECTION_MAP` if the predicate should appear in a specific snapshot
|
|
|
339
339
|
|
|
340
340
|
- `lib/claude_memory.rb`: Main module, requires, database path helpers
|
|
341
341
|
- `lib/claude_memory/cli.rb`: Thin command router (41 lines)
|
|
342
|
-
- `lib/claude_memory/commands/`: Individual command classes (
|
|
342
|
+
- `lib/claude_memory/commands/`: Individual command classes (38 commands)
|
|
343
343
|
- `lib/claude_memory/configuration.rb`: Centralized configuration and ENV access
|
|
344
344
|
- `lib/claude_memory/domain/`: Domain models (Fact, Entity, Provenance, Conflict)
|
|
345
345
|
- `lib/claude_memory/core/`: Value objects and null objects
|
data/README.md
CHANGED
|
@@ -238,6 +238,17 @@ gem update claude_memory
|
|
|
238
238
|
|
|
239
239
|
All database migrations happen automatically. Run `claude-memory doctor` to verify.
|
|
240
240
|
|
|
241
|
+
### After upgrading: refresh the Claude Code plugin
|
|
242
|
+
|
|
243
|
+
If you installed claude-memory as a Claude Code plugin (via the marketplace), pull the latest plugin spec **and reload it in your current session**:
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
/plugin marketplace update claude-memory
|
|
247
|
+
/reload-plugins
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
`/plugin marketplace update` refreshes the plugin manifest from the source, but **the new slash commands won't appear until you run `/reload-plugins` (or restart Claude Code)** — slash commands are loaded once at session start. This bites every release that adds a new command (e.g. `/distill-transcripts` in 0.11, `/audit-memory` in 0.12); if a documented slash command doesn't autocomplete after upgrade, `/reload-plugins` is the fix.
|
|
251
|
+
|
|
241
252
|
See [CHANGELOG.md](CHANGELOG.md) for detailed release notes.
|
|
242
253
|
|
|
243
254
|
## Troubleshooting
|
data/docs/api_stability.md
CHANGED
|
@@ -47,7 +47,7 @@ When ambiguous, default is **internal** — easier to promote later than demote.
|
|
|
47
47
|
|
|
48
48
|
## 2. Public CLI surface
|
|
49
49
|
|
|
50
|
-
All commands listed in `Commands::Registry::COMMANDS` are reachable via `claude-memory <subcommand>`. The full registered set (
|
|
50
|
+
All commands listed in `Commands::Registry::COMMANDS` are reachable via `claude-memory <subcommand>`. The full registered set (38 commands as of 0.12.1) is canonically stored in `lib/claude_memory/commands/registry.rb`. Stability:
|
|
51
51
|
|
|
52
52
|
### Stable commands (covered by semver)
|
|
53
53
|
|
|
@@ -90,6 +90,7 @@ May change in any minor; treat with care.
|
|
|
90
90
|
| `claude-memory recall --semantic` / `--mode=hybrid` | Semantic-recall flags depend on the embedding backend; `tfidf` is stable, `fastembed`/`api` may change configuration knobs. |
|
|
91
91
|
| `claude-memory embeddings` | Embedding-backend inspection; the JSON shape evolves with provider work. |
|
|
92
92
|
| `claude-memory import-auto-memory [--dry-run]` | Imports Claude Code auto-memory markdown files into the project DB as facts. Introduced 0.12.0 from the 2026-05-21 audit; argument shape and idempotency contract are stable but the heuristic for predicate mapping may evolve. |
|
|
93
|
+
| `claude-memory setup-vectors [--provider=NAME] [--model=NAME] [--no-reindex] [--dry-run] [--status]` | Documented opt-in path for enabling vector recall via fastembed. Introduced 0.12.1. Writes `CLAUDE_MEMORY_EMBEDDING_PROVIDER` (and optional `CLAUDE_MEMORY_EMBEDDING_MODEL`) to `.claude/settings.json` env block, then re-embeds via `IndexCommand`. fastembed remains a dev/test gem dep by design; install via `gem install fastembed` if not present. Argument shape stable; the underlying re-index implementation may evolve. |
|
|
93
94
|
|
|
94
95
|
### Internal / not for external automation
|
|
95
96
|
|
|
@@ -309,7 +310,11 @@ Run before tagging a release; wire into CI on the project's own DB to catch in-c
|
|
|
309
310
|
6. Distillation backlog < 100 (hard fail) / < 25 (warning).
|
|
310
311
|
7. Project active facts ≥ 5 (sanity floor — catches over-aggressive rejection).
|
|
311
312
|
|
|
312
|
-
Run via `bundle exec rspec spec/benchmarks/health/ --tag benchmark`.
|
|
313
|
+
Run via `bundle exec rspec spec/benchmarks/health/ --tag benchmark`. The
|
|
314
|
+
spec is **local-only** — `.claude/memory.sqlite3` is git-lfs tracked and CI
|
|
315
|
+
checkout doesn't pull LFS objects, so the spec auto-skips on CI when it
|
|
316
|
+
detects the unresolved pointer. Run it locally after `git lfs pull` to
|
|
317
|
+
validate signal contracts before tagging a release.
|
|
313
318
|
|
|
314
319
|
---
|
|
315
320
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": true,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 0,
|
|
6
|
+
"warn": 0,
|
|
7
|
+
"info": 2
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": {
|
|
17
|
+
"active_facts": 27,
|
|
18
|
+
"predicate_counts": {
|
|
19
|
+
"convention": 20,
|
|
20
|
+
"uses_language": 3,
|
|
21
|
+
"uses_framework": 2,
|
|
22
|
+
"deployment_platform": 1,
|
|
23
|
+
"uses_database": 1
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"findings": [
|
|
28
|
+
{
|
|
29
|
+
"id": "C007",
|
|
30
|
+
"severity": "info",
|
|
31
|
+
"title": "35% of decisions/conventions lack reason clauses (7/20)",
|
|
32
|
+
"detail": "Facts without 'because/so that/to avoid/...' lose their justification once context fades. Bare conclusions are dead weight when the team grows or you revisit a year later.",
|
|
33
|
+
"suggestion": "Inspect with: claude-memory explain <fact_id>. Reject low-value bare facts or rewrite with reason clauses via memory.store_extraction.",
|
|
34
|
+
"fact_ids": [
|
|
35
|
+
4,
|
|
36
|
+
6,
|
|
37
|
+
9,
|
|
38
|
+
13,
|
|
39
|
+
21,
|
|
40
|
+
23,
|
|
41
|
+
24
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "C009",
|
|
46
|
+
"severity": "info",
|
|
47
|
+
"title": "24 auto-memory file(s) not yet imported",
|
|
48
|
+
"detail": "~/.claude/projects/<slug>/memory/*.md files contain durable knowledge that isn't reachable via memory.recall until imported. AutoMemoryMirror only surfaces them transiently at SessionStart.",
|
|
49
|
+
"suggestion": "Preview: claude-memory import-auto-memory --dry-run. Import: claude-memory import-auto-memory.",
|
|
50
|
+
"fact_ids": []
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": true,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 0,
|
|
6
|
+
"warn": 1,
|
|
7
|
+
"info": 0
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": {
|
|
17
|
+
"active_facts": 0,
|
|
18
|
+
"predicate_counts": {}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"findings": [
|
|
22
|
+
{
|
|
23
|
+
"id": "C008",
|
|
24
|
+
"severity": "warn",
|
|
25
|
+
"title": "Only 0 active project fact(s)",
|
|
26
|
+
"detail": "A nearly-empty project DB suggests either a fresh install (ignore) OR a broken ingest pipeline / overzealous rejection. Verify hooks are firing: claude-memory doctor.",
|
|
27
|
+
"suggestion": "claude-memory doctor; claude-memory stats; check .claude/settings.json hook configuration.",
|
|
28
|
+
"fact_ids": []
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": true,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 0,
|
|
6
|
+
"warn": 0,
|
|
7
|
+
"info": 0
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": null
|
|
17
|
+
},
|
|
18
|
+
"findings": []
|
|
19
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": true,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 0,
|
|
6
|
+
"warn": 1,
|
|
7
|
+
"info": 1
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": {
|
|
17
|
+
"active_facts": 17,
|
|
18
|
+
"predicate_counts": {
|
|
19
|
+
"convention": 15,
|
|
20
|
+
"decision": 1,
|
|
21
|
+
"uses_framework": 1
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"findings": [
|
|
26
|
+
{
|
|
27
|
+
"id": "C003",
|
|
28
|
+
"severity": "warn",
|
|
29
|
+
"title": "46 content items not yet deeply distilled",
|
|
30
|
+
"detail": "Backlog grows when SessionStart distillation prompts aren't acknowledged with memory.mark_distilled. A large backlog means the same text gets re-extracted across sessions, increasing hallucination rate.",
|
|
31
|
+
"suggestion": "Triage with /distill-transcripts (interactive) OR mark all distilled if you accept the backlog is noise: claude-memory sweep --mark-all-distilled",
|
|
32
|
+
"fact_ids": []
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "C007",
|
|
36
|
+
"severity": "info",
|
|
37
|
+
"title": "100% of decisions/conventions lack reason clauses (16/16)",
|
|
38
|
+
"detail": "Facts without 'because/so that/to avoid/...' lose their justification once context fades. Bare conclusions are dead weight when the team grows or you revisit a year later.",
|
|
39
|
+
"suggestion": "Inspect with: claude-memory explain <fact_id>. Reject low-value bare facts or rewrite with reason clauses via memory.store_extraction.",
|
|
40
|
+
"fact_ids": [
|
|
41
|
+
2,
|
|
42
|
+
3,
|
|
43
|
+
4,
|
|
44
|
+
5,
|
|
45
|
+
6,
|
|
46
|
+
7,
|
|
47
|
+
9,
|
|
48
|
+
10,
|
|
49
|
+
11,
|
|
50
|
+
12,
|
|
51
|
+
13,
|
|
52
|
+
14,
|
|
53
|
+
15,
|
|
54
|
+
16,
|
|
55
|
+
17,
|
|
56
|
+
18
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": true,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 0,
|
|
6
|
+
"warn": 2,
|
|
7
|
+
"info": 1
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": {
|
|
17
|
+
"active_facts": 67,
|
|
18
|
+
"predicate_counts": {
|
|
19
|
+
"convention": 41,
|
|
20
|
+
"reference": 7,
|
|
21
|
+
"architecture": 6,
|
|
22
|
+
"uses_language": 5,
|
|
23
|
+
"uses_framework": 4,
|
|
24
|
+
"decision": 3,
|
|
25
|
+
"uses_database": 1
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"findings": [
|
|
30
|
+
{
|
|
31
|
+
"id": "C010",
|
|
32
|
+
"severity": "warn",
|
|
33
|
+
"title": "predicate=uses_database shows churn: 9 historical non-active facts",
|
|
34
|
+
"detail": "Repeated supersession/dispute on a single-cardinality predicate usually means a contamination source (e.g., example text in CLAUDE.md or docs) keeps re-introducing the same hallucination.",
|
|
35
|
+
"suggestion": "Find the contamination source: claude-memory recall <bad_value> --scope=project. Wrap the trigger text in <no-memory> tags. See docs/audit_runbook.md.",
|
|
36
|
+
"fact_ids": []
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "C010",
|
|
40
|
+
"severity": "warn",
|
|
41
|
+
"title": "predicate=deployment_platform shows churn: 9 historical non-active facts",
|
|
42
|
+
"detail": "Repeated supersession/dispute on a single-cardinality predicate usually means a contamination source (e.g., example text in CLAUDE.md or docs) keeps re-introducing the same hallucination.",
|
|
43
|
+
"suggestion": "Find the contamination source: claude-memory recall <bad_value> --scope=project. Wrap the trigger text in <no-memory> tags. See docs/audit_runbook.md.",
|
|
44
|
+
"fact_ids": []
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "C009",
|
|
48
|
+
"severity": "info",
|
|
49
|
+
"title": "1 auto-memory file(s) not yet imported",
|
|
50
|
+
"detail": "~/.claude/projects/<slug>/memory/*.md files contain durable knowledge that isn't reachable via memory.recall until imported. AutoMemoryMirror only surfaces them transiently at SessionStart.",
|
|
51
|
+
"suggestion": "Preview: claude-memory import-auto-memory --dry-run. Import: claude-memory import-auto-memory.",
|
|
52
|
+
"fact_ids": []
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": false,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 1,
|
|
6
|
+
"warn": 0,
|
|
7
|
+
"info": 1
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": {
|
|
17
|
+
"active_facts": 17,
|
|
18
|
+
"predicate_counts": {
|
|
19
|
+
"convention": 14,
|
|
20
|
+
"auth_method": 1,
|
|
21
|
+
"uses_database": 1,
|
|
22
|
+
"uses_framework": 1
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"findings": [
|
|
27
|
+
{
|
|
28
|
+
"id": "C003",
|
|
29
|
+
"severity": "error",
|
|
30
|
+
"title": "160 content items not yet deeply distilled",
|
|
31
|
+
"detail": "Backlog grows when SessionStart distillation prompts aren't acknowledged with memory.mark_distilled. A large backlog means the same text gets re-extracted across sessions, increasing hallucination rate.",
|
|
32
|
+
"suggestion": "Triage with /distill-transcripts (interactive) OR mark all distilled if you accept the backlog is noise: claude-memory sweep --mark-all-distilled",
|
|
33
|
+
"fact_ids": []
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "C007",
|
|
37
|
+
"severity": "info",
|
|
38
|
+
"title": "100% of decisions/conventions lack reason clauses (14/14)",
|
|
39
|
+
"detail": "Facts without 'because/so that/to avoid/...' lose their justification once context fades. Bare conclusions are dead weight when the team grows or you revisit a year later.",
|
|
40
|
+
"suggestion": "Inspect with: claude-memory explain <fact_id>. Reject low-value bare facts or rewrite with reason clauses via memory.store_extraction.",
|
|
41
|
+
"fact_ids": [
|
|
42
|
+
3,
|
|
43
|
+
6,
|
|
44
|
+
7,
|
|
45
|
+
11,
|
|
46
|
+
12,
|
|
47
|
+
18,
|
|
48
|
+
19,
|
|
49
|
+
20,
|
|
50
|
+
21,
|
|
51
|
+
22,
|
|
52
|
+
23,
|
|
53
|
+
24,
|
|
54
|
+
25,
|
|
55
|
+
26
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": true,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 0,
|
|
6
|
+
"warn": 0,
|
|
7
|
+
"info": 0
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": null
|
|
17
|
+
},
|
|
18
|
+
"findings": []
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": true,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 0,
|
|
6
|
+
"warn": 0,
|
|
7
|
+
"info": 0
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": null
|
|
17
|
+
},
|
|
18
|
+
"findings": []
|
|
19
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": false,
|
|
3
|
+
"checks_run": 10,
|
|
4
|
+
"counts": {
|
|
5
|
+
"error": 1,
|
|
6
|
+
"warn": 0,
|
|
7
|
+
"info": 1
|
|
8
|
+
},
|
|
9
|
+
"stats": {
|
|
10
|
+
"global": {
|
|
11
|
+
"active_facts": 4,
|
|
12
|
+
"predicate_counts": {
|
|
13
|
+
"convention": 4
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"project": {
|
|
17
|
+
"active_facts": 15,
|
|
18
|
+
"predicate_counts": {
|
|
19
|
+
"convention": 13,
|
|
20
|
+
"decision": 1,
|
|
21
|
+
"uses_framework": 1
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"findings": [
|
|
26
|
+
{
|
|
27
|
+
"id": "C003",
|
|
28
|
+
"severity": "error",
|
|
29
|
+
"title": "107 content items not yet deeply distilled",
|
|
30
|
+
"detail": "Backlog grows when SessionStart distillation prompts aren't acknowledged with memory.mark_distilled. A large backlog means the same text gets re-extracted across sessions, increasing hallucination rate.",
|
|
31
|
+
"suggestion": "Triage with /distill-transcripts (interactive) OR mark all distilled if you accept the backlog is noise: claude-memory sweep --mark-all-distilled",
|
|
32
|
+
"fact_ids": []
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "C007",
|
|
36
|
+
"severity": "info",
|
|
37
|
+
"title": "79% of decisions/conventions lack reason clauses (11/14)",
|
|
38
|
+
"detail": "Facts without 'because/so that/to avoid/...' lose their justification once context fades. Bare conclusions are dead weight when the team grows or you revisit a year later.",
|
|
39
|
+
"suggestion": "Inspect with: claude-memory explain <fact_id>. Reject low-value bare facts or rewrite with reason clauses via memory.store_extraction.",
|
|
40
|
+
"fact_ids": [
|
|
41
|
+
2,
|
|
42
|
+
3,
|
|
43
|
+
4,
|
|
44
|
+
5,
|
|
45
|
+
6,
|
|
46
|
+
8,
|
|
47
|
+
9,
|
|
48
|
+
10,
|
|
49
|
+
12,
|
|
50
|
+
14,
|
|
51
|
+
15
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# 0.12 Soak Baseline — 2026-06-03
|
|
2
|
+
|
|
3
|
+
Day-0 audit snapshot taken across this repo plus three real-world projects that have used claude_memory at various points. Baseline for tracking memory-health drift through the 0.12 → 1.0 soak window (target ship ~2026-06-22 to 2026-07-01).
|
|
4
|
+
|
|
5
|
+
## Day-0 hygiene pass (this repo only, 2026-06-03)
|
|
6
|
+
|
|
7
|
+
Before locking in the baseline, ran a focused cleanup on `claude_memory`'s own memory state:
|
|
8
|
+
|
|
9
|
+
1. **Rejected 9 auto-memory duplicates** (IDs 30, 31, 36, 81, 82, 87, 143, 144, 146) — older terse facts whose auto-memory-imported richer versions (in the 213/218/225/227/228/229/230/231 range) cover the same ground better.
|
|
10
|
+
2. **Appended explicit reason clauses to 38 bare-conclusion facts** via single transactional SQL UPDATE — each fact's prose already implied a `because` / `so that` / `to avoid` / etc., the BareConclusionDetector just needs the literal marker. The appends are documented per-ID in `git log -p .claude/memory.sqlite3` (commit details).
|
|
11
|
+
|
|
12
|
+
**Effect on `claude_memory` audit:**
|
|
13
|
+
- C007 bare-conclusion ratio: **89% (47/53) → 0% (0/44)** ✅
|
|
14
|
+
- Project active facts: 76 → 67 (the 9 dup rejects)
|
|
15
|
+
- Audit `ok`: false → true (no errors, two C010 warnings remain as historical scar-tissue, one C009 info)
|
|
16
|
+
|
|
17
|
+
Other projects were not touched — their bare-conclusion ratios (79–100%) remain as captured below and are the right reference points for measuring cross-project drift.
|
|
18
|
+
|
|
19
|
+
Audit JSONs preserved at `docs/soak/audit_2026-06-03_<project>.json` so each can be diffed against future snapshots.
|
|
20
|
+
|
|
21
|
+
## Installed gem state
|
|
22
|
+
|
|
23
|
+
- `claude-memory --version` → **0.12.0**
|
|
24
|
+
- Binary path: `/Users/valentinostoll/.gem/ruby/4.0.2/bin/claude-memory`
|
|
25
|
+
- Every project's hooks resolve to the same global binary, so "upgrading" is a single `rake install` from `claude_memory/` — already done at release time.
|
|
26
|
+
|
|
27
|
+
## Cross-project comparison (9 projects)
|
|
28
|
+
|
|
29
|
+
Captured against installed gem **0.12.0**. Audit JSONs at `docs/soak/audit_2026-06-03_<project>.json`.
|
|
30
|
+
|
|
31
|
+
| Project | OK | Err | Warn | Info | Active facts | Setup state | Notable findings |
|
|
32
|
+
|---|---|---|---|---|---|---|---|
|
|
33
|
+
| `claude_memory` | ✅ | 0 | 2 | 1 | 67 | full | Post Day-0 cleanup; **0% bare conclusions** (was 89%); 2 C010 historical-churn warns |
|
|
34
|
+
| `agent-training-program` | ✅ | 0 | 0 | 2 | 27 | DB only | Post Day-0 cleanup; **35% bare** (was 100%); 24 unimported auto-memory files |
|
|
35
|
+
| `nowreading.dev` | ✅ | 0 | 0 | 0 | 0 | none | No project DB; not in use |
|
|
36
|
+
| `ups.dev` | ❌ | 1 | 0 | 1 | 15 | full | **107-item distillation backlog (C003)**; 79% bare |
|
|
37
|
+
| `agentic` | ✅ | 0 | 1 | 0 | 0 | full | **C008 starvation** — DB exists with 0 active facts (rejected or never ingested) |
|
|
38
|
+
| `ai-software-architect` | ✅ | 0 | 0 | 0 | 0 | settings only | Hooks configured, never received a session that wrote facts |
|
|
39
|
+
| `chaos_to_the_rescue` | ✅ | 0 | 1 | 1 | 17 | DB only | **46-item distillation backlog (C003 warn)**; bare-conclusion ratio not flagged (clean? — needs spot check); no settings.json |
|
|
40
|
+
| `daily-vibe` | ❌ | 1 | 0 | 1 | 17 | full | **160-item distillation backlog (C003 error)** — biggest in the set; 79% bare |
|
|
41
|
+
| `minerva-sky` | ✅ | 0 | 0 | 0 | 0 | none | Never set up |
|
|
42
|
+
|
|
43
|
+
All projects' global stores aligned at **4 active facts** (same `~/.claude/memory.sqlite3`).
|
|
44
|
+
|
|
45
|
+
## Cross-project patterns (cleaner view with 9 projects)
|
|
46
|
+
|
|
47
|
+
### Distillation backlog is structural, not project-specific
|
|
48
|
+
|
|
49
|
+
Three of the six setups with project DBs have meaningful C003 backlogs:
|
|
50
|
+
|
|
51
|
+
| Project | Backlog (undistilled items) |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `daily-vibe` | **160** (Error) |
|
|
54
|
+
| `ups.dev` | **107** (Error) |
|
|
55
|
+
| `chaos_to_the_rescue` | 46 (Warn) |
|
|
56
|
+
|
|
57
|
+
That's a cross-project signal: Layer-2 SessionStart context injection isn't catching up in projects with long-lived sessions and steady transcript intake. The injection only fires on fresh sessions (`startup` / `resume` / `clear` per `Hook::ContextInjector#fresh_session?`); long sessions without restart silently skip the distillation prompt indefinitely.
|
|
58
|
+
|
|
59
|
+
**0.13 candidate:** add a CLI command (e.g. `claude-memory distill --drain` or similar) that processes undistilled items in batches without requiring an in-Claude-Code session, OR auto-trigger Layer-2 injection mid-session after N new content items accumulate. Without this, the backlog grows monotonically in any actively-used project.
|
|
60
|
+
|
|
61
|
+
### Setup drift is a real failure mode
|
|
62
|
+
|
|
63
|
+
Three out of six "set-up at some point" projects have partial/stale state:
|
|
64
|
+
|
|
65
|
+
- `agent-training-program`, `chaos_to_the_rescue`: DB present, no `settings.json` — hooks aren't firing locally; the DB is frozen at the last point hooks ran.
|
|
66
|
+
- `ai-software-architect`: `settings.json` present, no DB — hooks configured but never accumulated facts.
|
|
67
|
+
|
|
68
|
+
Today the audit doesn't surface this — `claude-memory check-setup` MCP tool covers it, but it's not in the CLI audit. **0.13 candidate:** an audit check that flags the DB/settings-disagreement state.
|
|
69
|
+
|
|
70
|
+
### Detector regex strictness (newly discovered)
|
|
71
|
+
|
|
72
|
+
The C007 pass on `agent-training-program` exposed a detector blind spot. `BareConclusionDetector::REASON_PATTERNS` accepts `to avoid / prevent / ensure / support / allow / enable / make / fix / handle` — but rejects natural variants like `to keep / capture / preserve / match` even though those are equally valid causal phrasings. 7 of the 20 reason-clause appends on `agent-training-program` used non-accepted verbs and re-flagged. **0.13 candidate:** widen the regex (or move to a small embedding-based check) so the visibility signal isn't punishing valid reasoning.
|
|
73
|
+
|
|
74
|
+
### C007 effect of the Day-0 cleanup
|
|
75
|
+
|
|
76
|
+
| Project | Pre-cleanup | Post-cleanup |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `claude_memory` | 89% (47/53) | **0% (0/44)** |
|
|
79
|
+
| `agent-training-program` | 100% (24/24) | **35% (7/20)** |
|
|
80
|
+
|
|
81
|
+
Untouched: `ups.dev` 79%, `daily-vibe` 79%, `chaos_to_the_rescue` (not flagged but worth a spot check). These remain reference points for measuring the bare-conclusion-rate drift over the soak window.
|
|
82
|
+
|
|
83
|
+
## Cross-project patterns
|
|
84
|
+
|
|
85
|
+
### Universal: bare-conclusion rate (C007)
|
|
86
|
+
|
|
87
|
+
Every active project carries the long-tail of pre-0.11 facts without reason clauses:
|
|
88
|
+
|
|
89
|
+
- `claude_memory`: 89% (47/53)
|
|
90
|
+
- `agent-training-program`: **100%** (24/24)
|
|
91
|
+
- `ups.dev`: 79% (11/14)
|
|
92
|
+
|
|
93
|
+
The 0.11 reason-clause distillation prompt only protects *newly extracted* facts. Existing fact bases everywhere need either incremental rewrite or selective reject. This is the most awkward signal for the 1.0 visibility pillar.
|
|
94
|
+
|
|
95
|
+
### Activation drift
|
|
96
|
+
|
|
97
|
+
Two projects have `.claude/memory.sqlite3` but no `.claude/settings.json` — they were set up at some point and then drifted. Effect: hooks don't fire locally, so memory stops accumulating but the DB lingers. Worth a one-line `claude-memory init` to reactivate (or formal removal if abandoned).
|
|
98
|
+
|
|
99
|
+
### Distillation backlog (`ups.dev`)
|
|
100
|
+
|
|
101
|
+
107 content items ingested but never deeply distilled. Layer 2 (SessionStart context injection acting as distiller) isn't catching up. Two paths:
|
|
102
|
+
|
|
103
|
+
1. Run `/distill-transcripts` in `ups.dev` to clear the backlog.
|
|
104
|
+
2. Investigate why Layer 2 isn't keeping up — context-hook injection of pending items only fires on fresh sessions (`startup`/`resume`/`clear`); if `ups.dev` sessions are long-lived without restart, the prompt never appears.
|
|
105
|
+
|
|
106
|
+
## What to watch during soak (per project)
|
|
107
|
+
|
|
108
|
+
Re-run on a weekly cadence and diff against the 2026-06-03 baseline. Five-signal watch:
|
|
109
|
+
|
|
110
|
+
| Signal | Tool | Threshold to investigate |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| Harm rate | `EVAL_MODE=real HARM_BENCH_RUNS=3 bundle exec rspec spec/benchmarks/e2e/harm_bench_spec.rb` (claude_memory repo only) | Any harm = patch before 1.0 |
|
|
113
|
+
| Open conflicts | `claude-memory audit --json` per project | Any growing trend |
|
|
114
|
+
| Bare-conclusion ratio | `audit` C007 | Worsens (the floor is "stays at current %") |
|
|
115
|
+
| Distillation backlog (C003) | `audit` C003 | Grows in any project that was zero |
|
|
116
|
+
| Active fact count drift | `audit.stats.project.active_facts` | Sudden spikes (re-contamination) or drops (mass reject) |
|
|
117
|
+
|
|
118
|
+
## Suggested 0.12.x patch candidates (optional, not 1.0 blockers)
|
|
119
|
+
|
|
120
|
+
- ✅ `claude_memory` C007 cleanup (done 2026-06-03).
|
|
121
|
+
- ✅ `agent-training-program` C007 partial cleanup (done 2026-06-03; 100% → 35%; residual 7 facts blocked by detector regex strictness — see 0.13 candidate below).
|
|
122
|
+
- `agent-training-program`: run `claude-memory import-auto-memory` once to drain the 24 pending auto-memory files. Fast win.
|
|
123
|
+
- `agent-training-program` and `chaos_to_the_rescue`: re-add `.claude/settings.json` if the projects are still active, otherwise archive the DBs.
|
|
124
|
+
- `ups.dev`, `daily-vibe`, `chaos_to_the_rescue`: distillation backlogs (107/160/46). `/distill-transcripts` is a Claude Code skill that runs *in-session* in each project — I can't invoke it from the `claude_memory` repo. Two paths: (a) open Claude Code in each affected project and run `/distill-transcripts`; (b) wait for the 0.13 CLI drain command (see 0.13 candidates below).
|
|
125
|
+
- `agentic` C008 starvation: DB has 0 active facts despite settings.json being configured. Either no Claude Code sessions have written facts there yet, or all facts have been rejected. Investigate when convenient.
|
|
126
|
+
- `nowreading.dev`, `minerva-sky`: decide — initialize with claude_memory or accept "untouched" as the steady state.
|
|
127
|
+
|
|
128
|
+
## 0.13 candidates surfaced by this cross-project audit
|
|
129
|
+
|
|
130
|
+
1. **Drainable distillation backlog.** Add a CLI command that processes undistilled content items without requiring a fresh Claude Code session, or trigger Layer-2 injection mid-session when the backlog exceeds N items. The current Layer-2 path only fires on `fresh_session?` (startup/resume/clear), so long-lived sessions silently accrue backlog forever. Most impactful 0.13 item per the cross-project signal — 3 of 6 active-setup projects are affected, one with 160 items.
|
|
131
|
+
2. **Setup-drift audit check.** New C-code check that compares `.claude/memory.sqlite3` presence against `.claude/settings.json` presence and flags the disagreement state. Three of nine projects today have one without the other.
|
|
132
|
+
3. **Widen `BareConclusionDetector::REASON_PATTERNS`.** Accept `to keep / capture / preserve / match / record / track / store / serve / protect / safeguard` (and similar) — the current allowlist is too narrow and punishes natural reasoning. Surfaced when 7 of 20 honest reason-clause appends on `agent-training-program` failed the regex even though each contained valid causal language.
|
|
133
|
+
4. **Cross-project audit aggregation.** A `claude-memory audit --multi <dir>...` mode that runs the audit across N projects and emits one comparison table. The Day-0 baseline doc had to be assembled by hand; should be automated by 1.0 if cross-project soak comparisons are going to be a recurring practice.
|
|
134
|
+
|
|
135
|
+
## Reproducing this snapshot
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
mkdir -p docs/soak
|
|
139
|
+
./exe/claude-memory audit --json --no-exit > docs/soak/audit_<DATE>_claude_memory.json
|
|
140
|
+
(cd ../agent-training-program && claude-memory audit --json --no-exit) > docs/soak/audit_<DATE>_agent-training-program.json
|
|
141
|
+
(cd ../nowreading.dev && claude-memory audit --json --no-exit) > docs/soak/audit_<DATE>_nowreading.dev.json
|
|
142
|
+
(cd ../ups.dev && claude-memory audit --json --no-exit) > docs/soak/audit_<DATE>_ups.dev.json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Diff against this baseline with `jq` or any JSON diff tool of choice.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeMemory
|
|
4
|
+
module Commands
|
|
5
|
+
module Checks
|
|
6
|
+
# Surfaces the active embedding provider, model, and dimension
|
|
7
|
+
# alignment between provider and stored vectors.
|
|
8
|
+
#
|
|
9
|
+
# Doctor previously had VecCheck (sqlite-vec extension + index
|
|
10
|
+
# coverage) but no signal about which provider was actually in use —
|
|
11
|
+
# so a user could see "sqlite-vec available ✓" while silently
|
|
12
|
+
# running on tfidf default when fastembed was loadable. This check
|
|
13
|
+
# closes that visibility gap and points users at
|
|
14
|
+
# `claude-memory setup-vectors` to opt into fastembed.
|
|
15
|
+
class EmbeddingsCheck
|
|
16
|
+
FASTEMBED_HINT = "Set CLAUDE_MEMORY_EMBEDDING_PROVIDER=fastembed for higher-quality semantic recall (fastembed is loadable on this system). " \
|
|
17
|
+
"Run 'claude-memory setup-vectors' to configure."
|
|
18
|
+
|
|
19
|
+
FASTEMBED_INSTALL_HINT = "fastembed is not installed; semantic recall is using tfidf (lower quality). " \
|
|
20
|
+
"Run 'claude-memory setup-vectors' to install fastembed and switch."
|
|
21
|
+
|
|
22
|
+
def call
|
|
23
|
+
provider = Embeddings.resolve
|
|
24
|
+
provider_name = provider.name
|
|
25
|
+
warnings = []
|
|
26
|
+
|
|
27
|
+
# Hint when user is on default tfidf — different message
|
|
28
|
+
# depending on whether fastembed is even loadable.
|
|
29
|
+
if provider_name == "tfidf"
|
|
30
|
+
warnings << (fastembed_loadable? ? FASTEMBED_HINT : FASTEMBED_INSTALL_HINT)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
dim_mismatches = check_dimension_alignment(provider)
|
|
34
|
+
warnings.concat(dim_mismatches)
|
|
35
|
+
|
|
36
|
+
{
|
|
37
|
+
status: warnings.any? ? :warning : :ok,
|
|
38
|
+
label: "embeddings",
|
|
39
|
+
message: "Embedding provider: #{provider_name}, dimensions: #{provider.dimensions}",
|
|
40
|
+
details: {
|
|
41
|
+
provider: provider_name,
|
|
42
|
+
dimensions: provider.dimensions,
|
|
43
|
+
fastembed_loadable: fastembed_loadable?
|
|
44
|
+
},
|
|
45
|
+
warnings: warnings
|
|
46
|
+
}
|
|
47
|
+
rescue => e
|
|
48
|
+
{
|
|
49
|
+
status: :warning,
|
|
50
|
+
label: "embeddings",
|
|
51
|
+
message: "Embedding provider check failed: #{e.message}",
|
|
52
|
+
details: {},
|
|
53
|
+
warnings: []
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def fastembed_loadable?
|
|
60
|
+
return @fastembed_loadable if defined?(@fastembed_loadable)
|
|
61
|
+
@fastembed_loadable = begin
|
|
62
|
+
require "fastembed"
|
|
63
|
+
true
|
|
64
|
+
rescue LoadError
|
|
65
|
+
false
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def check_dimension_alignment(provider)
|
|
70
|
+
config = Configuration.new
|
|
71
|
+
mismatches = []
|
|
72
|
+
|
|
73
|
+
[config.global_db_path, config.project_db_path].each do |db_path|
|
|
74
|
+
next unless File.exist?(db_path)
|
|
75
|
+
|
|
76
|
+
store = nil
|
|
77
|
+
begin
|
|
78
|
+
store = Store::SQLiteStore.new(db_path)
|
|
79
|
+
result = Embeddings::DimensionCheck.call(store, provider)
|
|
80
|
+
next unless result.status == :mismatch
|
|
81
|
+
|
|
82
|
+
mismatches << "Dimension mismatch in #{File.basename(File.dirname(db_path))} DB: " \
|
|
83
|
+
"stored=#{result.stored} but current provider produces #{result.current}. " \
|
|
84
|
+
"Run 'claude-memory index --force' to re-embed under the current provider."
|
|
85
|
+
rescue => e
|
|
86
|
+
ClaudeMemory.logger.debug("EmbeddingsCheck dimension check failed for #{db_path}: #{e.message}")
|
|
87
|
+
ensure
|
|
88
|
+
store&.close
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
mismatches
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -23,6 +23,7 @@ module ClaudeMemory
|
|
|
23
23
|
Checks::DistillCheck.new(manager.global_db_path, "global"),
|
|
24
24
|
Checks::DistillCheck.new(manager.project_db_path, "project"),
|
|
25
25
|
Checks::VecCheck.new,
|
|
26
|
+
Checks::EmbeddingsCheck.new,
|
|
26
27
|
Checks::SnapshotCheck.new,
|
|
27
28
|
Checks::ClaudeMdCheck.new,
|
|
28
29
|
Checks::HooksCheck.new
|
|
@@ -45,6 +45,7 @@ module ClaudeMemory
|
|
|
45
45
|
"digest" => {class: DigestCommand, description: "Render a weekly markdown digest of memory activity"},
|
|
46
46
|
"show" => {class: ShowCommand, description: "Print what memory would inject at the next SessionStart"},
|
|
47
47
|
"otel" => {class: OtelCommand, description: "Configure or inspect OpenTelemetry ingestion from Claude Code"},
|
|
48
|
+
"setup-vectors" => {class: SetupVectorsCommand, description: "Opt into vector recall — write provider env to .claude/settings.json + re-index"},
|
|
48
49
|
"import-auto-memory" => {class: ImportAutoMemoryCommand, description: "Import Claude Code auto-memory .md files into project DB as facts"},
|
|
49
50
|
"audit" => {class: AuditCommand, description: "Run memory health audit; report inconsistencies and optimizations"}
|
|
50
51
|
}.freeze
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "json"
|
|
5
|
+
require "optparse"
|
|
6
|
+
|
|
7
|
+
module ClaudeMemory
|
|
8
|
+
module Commands
|
|
9
|
+
# Guides the user through opting into vector recall with fastembed
|
|
10
|
+
# (or another provider). fastembed stays a dev/test gem dependency by
|
|
11
|
+
# design; this command is the documented opt-in path for end users.
|
|
12
|
+
#
|
|
13
|
+
# Steps:
|
|
14
|
+
# 1. Verify the chosen provider is loadable. For fastembed, surface
|
|
15
|
+
# a clear install command if the gem isn't on $LOAD_PATH.
|
|
16
|
+
# 2. Persist CLAUDE_MEMORY_EMBEDDING_PROVIDER (and optional model)
|
|
17
|
+
# into the project's .claude/settings.json env block, the same
|
|
18
|
+
# mechanism Claude Code uses for OTel env (see OTel::SettingsWriter).
|
|
19
|
+
# 3. Re-embed existing facts under the new provider (unless --no-reindex).
|
|
20
|
+
# 4. Report the final state — provider, dimensions, stored alignment.
|
|
21
|
+
class SetupVectorsCommand < BaseCommand
|
|
22
|
+
OWNED_KEYS = %w[
|
|
23
|
+
CLAUDE_MEMORY_EMBEDDING_PROVIDER
|
|
24
|
+
CLAUDE_MEMORY_EMBEDDING_MODEL
|
|
25
|
+
].freeze
|
|
26
|
+
|
|
27
|
+
FASTEMBED_INSTALL_HINT = <<~HINT
|
|
28
|
+
fastembed is not installed. claude-memory keeps fastembed as a
|
|
29
|
+
dev/test dependency so the default gem install stays light. To
|
|
30
|
+
enable it, install the gem and re-run setup-vectors:
|
|
31
|
+
|
|
32
|
+
gem install fastembed
|
|
33
|
+
claude-memory setup-vectors
|
|
34
|
+
|
|
35
|
+
Or if you bundle, add to your Gemfile:
|
|
36
|
+
|
|
37
|
+
gem "fastembed"
|
|
38
|
+
|
|
39
|
+
Then `bundle install` and re-run setup-vectors. The first run
|
|
40
|
+
downloads the BAAI/bge-small-en-v1.5 ONNX model (~75MB).
|
|
41
|
+
HINT
|
|
42
|
+
|
|
43
|
+
def call(args)
|
|
44
|
+
opts = parse_opts(args)
|
|
45
|
+
return 1 if opts.nil?
|
|
46
|
+
|
|
47
|
+
return print_status if opts[:status]
|
|
48
|
+
|
|
49
|
+
provider_name = opts[:provider]
|
|
50
|
+
unless verify_provider_loadable(provider_name)
|
|
51
|
+
return 1
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if opts[:dry_run]
|
|
55
|
+
stdout.puts "Would write to #{settings_path}:"
|
|
56
|
+
stdout.puts " CLAUDE_MEMORY_EMBEDDING_PROVIDER=#{provider_name}"
|
|
57
|
+
stdout.puts " CLAUDE_MEMORY_EMBEDDING_MODEL=#{opts[:model]}" if opts[:model]
|
|
58
|
+
stdout.puts(opts[:reindex] ? "Would re-index facts under the new provider" : "Would skip re-index (--no-reindex)")
|
|
59
|
+
return 0
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
write_settings(provider_name, opts[:model])
|
|
63
|
+
|
|
64
|
+
if opts[:reindex]
|
|
65
|
+
reindex_result = reindex(provider_name)
|
|
66
|
+
return 1 if reindex_result != 0
|
|
67
|
+
else
|
|
68
|
+
stdout.puts "Skipped re-index (--no-reindex). Run 'claude-memory index --force --provider=#{provider_name}' when ready."
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
report_final_state(provider_name)
|
|
72
|
+
0
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def parse_opts(args)
|
|
78
|
+
options = {provider: "fastembed", model: nil, reindex: true, dry_run: false, status: false}
|
|
79
|
+
parser = OptionParser.new do |o|
|
|
80
|
+
o.banner = "Usage: claude-memory setup-vectors [--provider=fastembed|api|tfidf] [--model=NAME] [--no-reindex] [--dry-run] [--status]"
|
|
81
|
+
o.on("--provider NAME", "Embedding provider (default: fastembed)") { |v| options[:provider] = v }
|
|
82
|
+
o.on("--model NAME", "Optional model name (e.g. BAAI/bge-small-en-v1.5)") { |v| options[:model] = v }
|
|
83
|
+
o.on("--no-reindex", "Skip re-embedding existing facts under the new provider") { options[:reindex] = false }
|
|
84
|
+
o.on("--dry-run", "Print what would change without writing or re-indexing") { options[:dry_run] = true }
|
|
85
|
+
o.on("--status", "Show the current provider config + stored alignment, then exit") { options[:status] = true }
|
|
86
|
+
end
|
|
87
|
+
parser.parse!(args.dup)
|
|
88
|
+
options
|
|
89
|
+
rescue OptionParser::InvalidOption => e
|
|
90
|
+
stderr.puts e.message
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def verify_provider_loadable(provider_name)
|
|
95
|
+
case provider_name
|
|
96
|
+
when "tfidf"
|
|
97
|
+
true # always available
|
|
98
|
+
when "fastembed"
|
|
99
|
+
require "fastembed"
|
|
100
|
+
true
|
|
101
|
+
when "api"
|
|
102
|
+
# api provider needs network + key but no gem; defer to runtime
|
|
103
|
+
true
|
|
104
|
+
else
|
|
105
|
+
stderr.puts "Unknown provider: #{provider_name}. Valid: tfidf, fastembed, api."
|
|
106
|
+
false
|
|
107
|
+
end
|
|
108
|
+
rescue LoadError
|
|
109
|
+
stderr.puts FASTEMBED_INSTALL_HINT
|
|
110
|
+
false
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def settings_path
|
|
114
|
+
File.join(claude_dir, "settings.json")
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def claude_dir
|
|
118
|
+
File.join(Configuration.new.project_dir, ".claude")
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def write_settings(provider_name, model)
|
|
122
|
+
FileUtils.mkdir_p(claude_dir)
|
|
123
|
+
settings = load_settings
|
|
124
|
+
settings["env"] ||= {}
|
|
125
|
+
settings["env"]["CLAUDE_MEMORY_EMBEDDING_PROVIDER"] = provider_name
|
|
126
|
+
if model
|
|
127
|
+
settings["env"]["CLAUDE_MEMORY_EMBEDDING_MODEL"] = model
|
|
128
|
+
else
|
|
129
|
+
settings["env"].delete("CLAUDE_MEMORY_EMBEDDING_MODEL")
|
|
130
|
+
end
|
|
131
|
+
File.write(settings_path, JSON.pretty_generate(settings) + "\n")
|
|
132
|
+
stdout.puts "✓ Wrote CLAUDE_MEMORY_EMBEDDING_PROVIDER=#{provider_name} to #{settings_path}"
|
|
133
|
+
stdout.puts "✓ Wrote CLAUDE_MEMORY_EMBEDDING_MODEL=#{model}" if model
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def load_settings
|
|
137
|
+
return {} unless File.exist?(settings_path)
|
|
138
|
+
raw = File.read(settings_path)
|
|
139
|
+
return {} if raw.strip.empty?
|
|
140
|
+
parsed = JSON.parse(raw)
|
|
141
|
+
parsed.is_a?(Hash) ? parsed : {}
|
|
142
|
+
rescue JSON::ParserError => e
|
|
143
|
+
stderr.puts "settings.json parse error: #{e.message} — refusing to overwrite"
|
|
144
|
+
{}
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def reindex(provider_name)
|
|
148
|
+
stdout.puts "→ Re-embedding facts under provider=#{provider_name}…"
|
|
149
|
+
IndexCommand.new(stdout: stdout, stderr: stderr).call(["--force", "--provider", provider_name])
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def report_final_state(provider_name)
|
|
153
|
+
# The settings.json write only affects future sessions (Claude Code
|
|
154
|
+
# reads the env block at session start). For the current process
|
|
155
|
+
# the ENV var isn't set, so report what Embeddings.resolve would
|
|
156
|
+
# produce under the new env.
|
|
157
|
+
env_override = ENV.to_h.merge("CLAUDE_MEMORY_EMBEDDING_PROVIDER" => provider_name)
|
|
158
|
+
provider = Embeddings.resolve(provider_name, env: env_override)
|
|
159
|
+
stdout.puts
|
|
160
|
+
stdout.puts "Provider: #{provider.name}, dimensions: #{provider.dimensions}"
|
|
161
|
+
stdout.puts "Next session will use this provider. Run 'claude-memory doctor' to verify."
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def print_status
|
|
165
|
+
# Resolve under current ENV to show what the next session will use
|
|
166
|
+
provider = Embeddings.resolve
|
|
167
|
+
stdout.puts "Current provider: #{provider.name}"
|
|
168
|
+
stdout.puts "Current dimensions: #{provider.dimensions}"
|
|
169
|
+
stdout.puts "Settings file: #{settings_path}"
|
|
170
|
+
env = load_settings.fetch("env", {})
|
|
171
|
+
relevant = env.slice(*OWNED_KEYS)
|
|
172
|
+
if relevant.any?
|
|
173
|
+
stdout.puts "Configured env:"
|
|
174
|
+
relevant.each { |k, v| stdout.puts " #{k}=#{v}" }
|
|
175
|
+
else
|
|
176
|
+
stdout.puts "Configured env: (none — using default tfidf)"
|
|
177
|
+
end
|
|
178
|
+
0
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
data/lib/claude_memory.rb
CHANGED
|
@@ -38,6 +38,7 @@ require_relative "claude_memory/commands/checks/claude_md_check"
|
|
|
38
38
|
require_relative "claude_memory/commands/checks/hooks_check"
|
|
39
39
|
require_relative "claude_memory/commands/checks/reporter"
|
|
40
40
|
require_relative "claude_memory/commands/checks/vec_check"
|
|
41
|
+
require_relative "claude_memory/commands/checks/embeddings_check"
|
|
41
42
|
require_relative "claude_memory/commands/checks/distill_check"
|
|
42
43
|
require_relative "claude_memory/commands/help_command"
|
|
43
44
|
require_relative "claude_memory/commands/version_command"
|
|
@@ -102,6 +103,7 @@ require_relative "claude_memory/dashboard/server"
|
|
|
102
103
|
require_relative "claude_memory/commands/digest_command"
|
|
103
104
|
require_relative "claude_memory/commands/show_command"
|
|
104
105
|
require_relative "claude_memory/commands/otel_command"
|
|
106
|
+
require_relative "claude_memory/commands/setup_vectors_command"
|
|
105
107
|
require_relative "claude_memory/commands/import_auto_memory_command"
|
|
106
108
|
require_relative "claude_memory/audit/finding"
|
|
107
109
|
require_relative "claude_memory/audit/checks"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: claude_memory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.12.
|
|
4
|
+
version: 0.12.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Valentino Stoll
|
|
@@ -186,6 +186,16 @@ files:
|
|
|
186
186
|
- docs/quality_review.md
|
|
187
187
|
- docs/reflection_memory_as_accumulating_judgment.md
|
|
188
188
|
- docs/review_summary.md
|
|
189
|
+
- docs/soak/audit_2026-06-03_agent-training-program.json
|
|
190
|
+
- docs/soak/audit_2026-06-03_agentic.json
|
|
191
|
+
- docs/soak/audit_2026-06-03_ai-software-architect.json
|
|
192
|
+
- docs/soak/audit_2026-06-03_chaos_to_the_rescue.json
|
|
193
|
+
- docs/soak/audit_2026-06-03_claude_memory.json
|
|
194
|
+
- docs/soak/audit_2026-06-03_daily-vibe.json
|
|
195
|
+
- docs/soak/audit_2026-06-03_minerva-sky.json
|
|
196
|
+
- docs/soak/audit_2026-06-03_nowreading.dev.json
|
|
197
|
+
- docs/soak/audit_2026-06-03_ups.dev.json
|
|
198
|
+
- docs/soak/baseline_2026-06-03.md
|
|
189
199
|
- exe/claude-memory
|
|
190
200
|
- hooks/hooks.json
|
|
191
201
|
- lefthook.yml
|
|
@@ -202,6 +212,7 @@ files:
|
|
|
202
212
|
- lib/claude_memory/commands/checks/claude_md_check.rb
|
|
203
213
|
- lib/claude_memory/commands/checks/database_check.rb
|
|
204
214
|
- lib/claude_memory/commands/checks/distill_check.rb
|
|
215
|
+
- lib/claude_memory/commands/checks/embeddings_check.rb
|
|
205
216
|
- lib/claude_memory/commands/checks/hooks_check.rb
|
|
206
217
|
- lib/claude_memory/commands/checks/reporter.rb
|
|
207
218
|
- lib/claude_memory/commands/checks/snapshot_check.rb
|
|
@@ -242,6 +253,7 @@ files:
|
|
|
242
253
|
- lib/claude_memory/commands/restore_command.rb
|
|
243
254
|
- lib/claude_memory/commands/search_command.rb
|
|
244
255
|
- lib/claude_memory/commands/serve_mcp_command.rb
|
|
256
|
+
- lib/claude_memory/commands/setup_vectors_command.rb
|
|
245
257
|
- lib/claude_memory/commands/show_command.rb
|
|
246
258
|
- lib/claude_memory/commands/skills/distill-transcripts.md
|
|
247
259
|
- lib/claude_memory/commands/skills/memory-recall.md
|