claude_memory 0.8.0 → 0.9.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 +94 -2
- data/.claude/settings.json +30 -52
- data/.claude/settings.local.json +3 -1
- data/.claude/skills/release/SKILL.md +168 -0
- data/.claude/skills/upgrade-dependencies/SKILL.md +154 -0
- data/.claude-plugin/marketplace.json +2 -2
- data/.claude-plugin/plugin.json +3 -3
- data/.claude-plugin/scripts/hook-runner.sh +14 -0
- data/.claude-plugin/scripts/serve-mcp.sh +14 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +47 -0
- data/CLAUDE.md +31 -17
- data/README.md +35 -0
- data/db/migrations/013_add_mcp_tool_calls.rb +26 -0
- data/db/migrations/014_canonicalize_predicates.rb +30 -0
- data/docs/improvements.md +58 -20
- data/docs/influence/claude-mem.md +1 -0
- data/docs/influence/claude-supermemory.md +1 -0
- data/docs/influence/episodic-memory.md +1 -0
- data/docs/influence/grepai.md +1 -0
- data/docs/influence/kbs.md +1 -0
- data/docs/influence/lossless-claw.md +1 -0
- data/docs/influence/qmd.md +1 -0
- data/lib/claude_memory/commands/completion_command.rb +1 -31
- data/lib/claude_memory/commands/embeddings_command.rb +198 -0
- data/lib/claude_memory/commands/help_command.rb +8 -1
- data/lib/claude_memory/commands/registry.rb +47 -34
- data/lib/claude_memory/commands/reject_command.rb +62 -0
- data/lib/claude_memory/commands/restore_command.rb +77 -0
- data/lib/claude_memory/commands/skills/distill-transcripts.md +5 -1
- data/lib/claude_memory/commands/stats_command.rb +98 -2
- data/lib/claude_memory/configuration.rb +14 -1
- data/lib/claude_memory/distill/json_schema.md +8 -4
- data/lib/claude_memory/distill/null_distiller.rb +2 -0
- data/lib/claude_memory/domain/entity.rb +13 -1
- data/lib/claude_memory/domain/fact.rb +26 -2
- data/lib/claude_memory/embeddings/api_adapter.rb +5 -4
- data/lib/claude_memory/embeddings/fastembed_adapter.rb +43 -13
- data/lib/claude_memory/embeddings/inspector.rb +91 -0
- data/lib/claude_memory/embeddings/model_registry.rb +210 -0
- data/lib/claude_memory/embeddings/resolver.rb +32 -6
- data/lib/claude_memory/ingest/ingester.rb +17 -0
- data/lib/claude_memory/mcp/handlers/management_handlers.rb +24 -0
- data/lib/claude_memory/mcp/handlers/stats_handlers.rb +5 -2
- data/lib/claude_memory/mcp/instructions_builder.rb +17 -0
- data/lib/claude_memory/mcp/server.rb +30 -3
- data/lib/claude_memory/mcp/telemetry.rb +86 -0
- data/lib/claude_memory/mcp/tool_definitions.rb +86 -3
- data/lib/claude_memory/mcp/tools.rb +10 -0
- data/lib/claude_memory/publish.rb +40 -5
- data/lib/claude_memory/recall.rb +81 -0
- data/lib/claude_memory/resolve/predicate_policy.rb +63 -3
- data/lib/claude_memory/resolve/resolver.rb +43 -0
- data/lib/claude_memory/store/schema_manager.rb +1 -1
- data/lib/claude_memory/store/sqlite_store.rb +250 -1
- data/lib/claude_memory/store/store_manager.rb +50 -1
- data/lib/claude_memory/sweep/maintenance.rb +115 -1
- data/lib/claude_memory/sweep/sweeper.rb +3 -0
- data/lib/claude_memory/version.rb +1 -1
- data/lib/claude_memory.rb +5 -0
- metadata +27 -8
- data/.claude/memory.sqlite3-shm +0 -0
- data/.claude/memory.sqlite3-wal +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Wrapper script for claude-memory MCP server.
|
|
3
|
+
# Used by the Claude Code plugin to launch the MCP server.
|
|
4
|
+
# Falls back to a JSON-RPC error if the gem is not installed.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
if command -v claude-memory > /dev/null 2>&1; then
|
|
9
|
+
exec claude-memory serve-mcp
|
|
10
|
+
else
|
|
11
|
+
# Return a JSON-RPC error so Claude Code surfaces it to the user
|
|
12
|
+
echo '{"jsonrpc":"2.0","id":1,"error":{"code":-32603,"message":"claude-memory gem not found. Install with: gem install claude_memory"}}'
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.0.
|
|
1
|
+
4.0.2
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,53 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.1] - 2026-04-16
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- MCP server now conforms to JSON-RPC 2.0: notifications (messages without an `id`) never receive a response. Previously, `notifications/initialized` — which Claude Code sends after every handshake — triggered a spurious `Method not found` error frame, causing strict MCP clients to mark the server failed on `/mcp` reconnect after the initial connection.
|
|
12
|
+
|
|
13
|
+
## [0.9.0] - 2026-04-16
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- `claude-memory reject <id_or_docid>` command + `memory.reject_fact` MCP tool — explicitly mark distiller hallucinations as wrong, closing associated conflicts
|
|
18
|
+
- `claude-memory restore --predicate NAME` command — recover facts that were superseded by obsolete single-value predicate classifications (uses Jaccard-based token overlap to distinguish bug-caused supersession from real corrections)
|
|
19
|
+
- MCP tool-call telemetry: `mcp_tool_calls` table records every tool invocation with timing, result counts, and error classification. `claude-memory stats --tools [--since DAYS]` for usage reporting. 90-day retention via Sweep
|
|
20
|
+
- `CLAUDE_CONFIG_DIR` env var support for non-standard Claude Code config locations
|
|
21
|
+
- Predicate synonym canonicalization at insert time (`has_convention` → `convention`, `primary_language` → `uses_language`). Prevents drift from fragmenting the knowledge graph
|
|
22
|
+
- Novel predicate warnings at insert time — logged when the Resolver encounters a predicate not in PredicatePolicy
|
|
23
|
+
- NullDistiller now emits `uses_language` facts for detected language entities
|
|
24
|
+
- Proactive memory recall guidance in MCP instructions — Claude now checks conventions before code generation, architecture before explanations, decisions before refactoring
|
|
25
|
+
- YARD documentation across 13 core source files (+473 lines)
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **`uses_framework` reclassified as multi-value** — real projects use multiple frameworks (Rails + Turbo + Tailwind). The prior single-value classification silently superseded valid facts in production databases. Run `claude-memory restore --predicate uses_framework` to recover affected facts
|
|
30
|
+
- `PredicatePolicy` is now the single source of truth for predicate vocabulary, snapshot section mapping, synonym canonicalization, and LLM guidance. `tool_definitions.rb`, `publish.rb`, and `distill-transcripts.md` all derive from the policy
|
|
31
|
+
- Predicate vocabulary curated from 13 → 8 based on multi-project usage data. Removed predicates (`preference`, `workflow`, `dependency`, `testing_strategy`, `tool_usage`, `ci_platform`, `primary_language`) had zero facts across all surveyed databases. They still work via DEFAULT_POLICY but are no longer advertised to the LLM
|
|
32
|
+
- `Registry::COMMANDS` stores `{class:, description:}` entries with direct class references instead of string class names
|
|
33
|
+
- Plugin and gem descriptions rewritten from mechanism-focused to outcome-focused
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- **`StatsCommand` broken in production** — used `Sequel.sqlite` which requires the unlisted `sqlite3` gem. Now uses the extralite adapter consistently
|
|
38
|
+
- Missing `embeddings` command in shell completion output
|
|
39
|
+
|
|
40
|
+
### Upgrade Notes
|
|
41
|
+
|
|
42
|
+
**Schema**: v12 → v14 (two automatic migrations). Migration 013 adds `mcp_tool_calls` table. Migration 014 canonicalizes stale predicate names (`has_convention` → `convention`, `primary_language` → `uses_language`) in existing facts.
|
|
43
|
+
|
|
44
|
+
**Action required for `uses_framework` recovery**: If your project uses multiple frameworks (Rails + Turbo + Tailwind, etc.), past sessions may have superseded valid facts. After upgrading, run:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
claude-memory restore --predicate uses_framework --dry-run # preview
|
|
48
|
+
claude-memory restore --predicate uses_framework # restore
|
|
49
|
+
claude-memory restore --predicate uses_framework --scope global # if needed for global DB
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Pruned predicates still work**: `preference`, `workflow`, `dependency`, `testing_strategy`, `tool_usage`, `ci_platform` fall through to the default multi-value policy. Existing facts with these predicates are unaffected. They'll appear as "novel" in `memory.stats` but function normally.
|
|
53
|
+
|
|
7
54
|
## [0.8.0] - 2026-03-30
|
|
8
55
|
|
|
9
56
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -15,6 +15,12 @@ ClaudeMemory is a Ruby gem that provides long-term, self-managed memory for Clau
|
|
|
15
15
|
|
|
16
16
|
**Check memory before exploring code.** Use `memory.recall`, `memory.decisions`, `memory.architecture`, or `memory.conventions` to find existing knowledge before reading files.
|
|
17
17
|
|
|
18
|
+
### Git Usage & Best Practices
|
|
19
|
+
|
|
20
|
+
- Before each commit, apply the quality-review skill
|
|
21
|
+
- Iteratively commit related changes with their tests
|
|
22
|
+
|
|
23
|
+
|
|
18
24
|
## Development Commands
|
|
19
25
|
|
|
20
26
|
### Setup
|
|
@@ -157,7 +163,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
157
163
|
- Each command is a separate class (HelpCommand, DoctorCommand, etc.)
|
|
158
164
|
- All commands inherit from BaseCommand
|
|
159
165
|
- Dependency injection for I/O (stdout, stderr, stdin)
|
|
160
|
-
-
|
|
166
|
+
- 28 commands total, each focused on single responsibility
|
|
161
167
|
|
|
162
168
|
- **`Configuration`**: Centralized ENV access (`configuration.rb`)
|
|
163
169
|
- Single source of truth for paths and environment variables
|
|
@@ -166,7 +172,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
166
172
|
#### Core Domain Layer
|
|
167
173
|
|
|
168
174
|
- **`Domain`**: Rich domain models with business logic (`domain/`)
|
|
169
|
-
- `Fact`: Facts with validation, status checking (active?, superseded?)
|
|
175
|
+
- `Fact`: Facts with validation, status checking (active?, superseded?, rejected?)
|
|
170
176
|
- `Entity`: Entities with type checking (database?, framework?)
|
|
171
177
|
- `Provenance`: Evidence with strength checking (stated?, inferred?)
|
|
172
178
|
- `Conflict`: Conflicts with status tracking (open?, resolved?)
|
|
@@ -182,7 +188,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
182
188
|
- **`Store`**: SQLite database access via Sequel (`store/`)
|
|
183
189
|
- `SQLiteStore`: Database operations
|
|
184
190
|
- `StoreManager`: Dual-database connection manager
|
|
185
|
-
- Schema includes: content_items, entities, facts, provenance, fact_links, conflicts
|
|
191
|
+
- Schema includes: content_items, entities, facts, provenance, fact_links, conflicts, mcp_tool_calls
|
|
186
192
|
- Transaction safety for multi-step operations
|
|
187
193
|
|
|
188
194
|
- **`Infrastructure`**: I/O abstractions (`infrastructure/`)
|
|
@@ -205,7 +211,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
205
211
|
|
|
206
212
|
- **`Resolve`**: Truth maintenance and conflict resolution (`resolve/`)
|
|
207
213
|
- Determines equivalence, supersession, or conflicts
|
|
208
|
-
- PredicatePolicy
|
|
214
|
+
- PredicatePolicy: single source of truth for predicate vocabulary, cardinality, section mapping, and synonym canonicalization
|
|
209
215
|
- Transaction safety for atomic operations
|
|
210
216
|
|
|
211
217
|
- **`Recall`**: Query interface for facts (`recall.rb`)
|
|
@@ -220,7 +226,8 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
220
226
|
- Modes: shared (repo), local (uncommitted), home (user directory)
|
|
221
227
|
|
|
222
228
|
- **`MCP`**: Model Context Protocol server and tools (`mcp/`)
|
|
223
|
-
- Exposes memory tools to Claude Code (
|
|
229
|
+
- Exposes memory tools to Claude Code (24 tools total)
|
|
230
|
+
- `Telemetry`: Records tool invocations to `mcp_tool_calls` table for usage stats
|
|
224
231
|
- Dual content/structuredContent responses with compact mode
|
|
225
232
|
|
|
226
233
|
- **`Hook`**: Hook entrypoint handlers (`hook/`)
|
|
@@ -238,6 +245,7 @@ Key tables (defined in `sqlite_store.rb`):
|
|
|
238
245
|
- `provenance`: Links facts to source content_items
|
|
239
246
|
- `fact_links`: Supersession and conflict relationships
|
|
240
247
|
- `conflicts`: Open contradictions
|
|
248
|
+
- `mcp_tool_calls`: MCP server tool invocation telemetry (schema v13)
|
|
241
249
|
|
|
242
250
|
Facts include:
|
|
243
251
|
- `scope`: "global" or "project" (determines applicability)
|
|
@@ -290,28 +298,34 @@ end
|
|
|
290
298
|
|
|
291
299
|
### Adding a New MCP Tool
|
|
292
300
|
|
|
293
|
-
1. Add tool definition to `
|
|
294
|
-
2.
|
|
295
|
-
3.
|
|
296
|
-
4.
|
|
301
|
+
1. Add tool definition to `ToolDefinitions.all` array in `lib/claude_memory/mcp/tool_definitions.rb`
|
|
302
|
+
2. Add `when` clause in `Tools#call` dispatch in `lib/claude_memory/mcp/tools.rb`
|
|
303
|
+
3. Implement handler method in the appropriate handler module in `mcp/handlers/`
|
|
304
|
+
4. Ensure tool queries appropriate database(s) via StoreManager
|
|
305
|
+
5. Add tests in `spec/claude_memory/mcp/`
|
|
297
306
|
|
|
298
307
|
### Modifying Database Schema
|
|
299
308
|
|
|
300
|
-
1. Increment `SCHEMA_VERSION` in `
|
|
301
|
-
2.
|
|
302
|
-
3.
|
|
309
|
+
1. Increment `SCHEMA_VERSION` in `store/schema_manager.rb`
|
|
310
|
+
2. Create a new Sequel migration file in `db/migrations/` (e.g., `013_add_mcp_tool_calls.rb`)
|
|
311
|
+
3. Sequel::Migrator runs migrations automatically in `ensure_schema!`
|
|
303
312
|
4. Test migration on existing database files
|
|
304
313
|
5. Update documentation if schema changes affect external interfaces
|
|
305
314
|
|
|
306
|
-
### Adding a New Predicate
|
|
315
|
+
### Adding a New Predicate
|
|
316
|
+
|
|
317
|
+
Edit `PredicatePolicy::POLICIES` in `lib/claude_memory/resolve/predicate_policy.rb` — this is the single source of truth. Choose cardinality:
|
|
318
|
+
|
|
319
|
+
- **single** (exclusive: true): Facts supersede or conflict (e.g., `uses_database` — one per project)
|
|
320
|
+
- **multi** (exclusive: false): Facts accumulate (e.g., `convention`, `uses_framework`)
|
|
307
321
|
|
|
308
|
-
|
|
322
|
+
Also update `SECTION_MAP` if the predicate should appear in a specific snapshot section (`:decisions`, `:conventions`, `:constraints`). The `ToolDefinitions` predicate list updates automatically via `PredicatePolicy.known_predicates`. Add entries to `SYNONYMS` if the distiller might emit variant names.
|
|
309
323
|
|
|
310
324
|
## Important Files
|
|
311
325
|
|
|
312
326
|
- `lib/claude_memory.rb`: Main module, requires, database path helpers
|
|
313
327
|
- `lib/claude_memory/cli.rb`: Thin command router (41 lines)
|
|
314
|
-
- `lib/claude_memory/commands/`: Individual command classes (
|
|
328
|
+
- `lib/claude_memory/commands/`: Individual command classes (28 commands)
|
|
315
329
|
- `lib/claude_memory/configuration.rb`: Centralized configuration and ENV access
|
|
316
330
|
- `lib/claude_memory/domain/`: Domain models (Fact, Entity, Provenance, Conflict)
|
|
317
331
|
- `lib/claude_memory/core/`: Value objects and null objects
|
|
@@ -326,12 +340,12 @@ Single-value predicates (like "uses_database") supersede old values. Multi-value
|
|
|
326
340
|
|
|
327
341
|
The gem includes an MCP server (`claude-memory serve-mcp`) that exposes memory operations as tools. Configuration should be in `.mcp.json` at project root.
|
|
328
342
|
|
|
329
|
-
Available MCP tools (
|
|
343
|
+
Available MCP tools (24 total):
|
|
330
344
|
- **Query & Recall**: `memory.recall`, `memory.recall_index`, `memory.recall_details`, `memory.recall_semantic`, `memory.search_concepts`
|
|
331
345
|
- **Provenance**: `memory.explain`, `memory.fact_graph`
|
|
332
346
|
- **Shortcuts**: `memory.decisions`, `memory.conventions`, `memory.architecture`
|
|
333
347
|
- **Context**: `memory.facts_by_tool`, `memory.facts_by_context`
|
|
334
|
-
- **Management**: `memory.promote`, `memory.store_extraction`
|
|
348
|
+
- **Management**: `memory.promote`, `memory.reject_fact`, `memory.store_extraction`
|
|
335
349
|
- **Distillation**: `memory.undistilled`, `memory.mark_distilled`
|
|
336
350
|
- **Monitoring**: `memory.status`, `memory.stats`, `memory.changes`, `memory.conflicts`
|
|
337
351
|
- **Maintenance**: `memory.sweep_now`
|
data/README.md
CHANGED
|
@@ -83,6 +83,41 @@ Claude: "Based on my memory, you're using Rails with PostgreSQL..."
|
|
|
83
83
|
👉 **[See Getting Started Guide →](docs/GETTING_STARTED.md)**
|
|
84
84
|
👉 **[View Example Conversations →](docs/EXAMPLES.md)**
|
|
85
85
|
|
|
86
|
+
## Why It Matters — Real A/B Test Results
|
|
87
|
+
|
|
88
|
+
We tested identical prompts with and without ClaudeMemory to measure the actual impact. Here's what we found:
|
|
89
|
+
|
|
90
|
+
### Architecture Recall Without File Traversal
|
|
91
|
+
|
|
92
|
+
> **Prompt:** "Explain the conflict detection and resolution system. Answer from knowledge only — do not read any files."
|
|
93
|
+
|
|
94
|
+
| | Without Memory | With Memory |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| **Response** | 16 lines: "I don't know this codebase — let me read the files" | 76 lines: correct 4-role PredicatePolicy explanation, resolution pipeline, specific examples |
|
|
97
|
+
| **Outcome** | Honest refusal — zero architectural understanding | Deep understanding without touching the filesystem |
|
|
98
|
+
|
|
99
|
+
### Correct File Paths vs Hallucinated Guesses
|
|
100
|
+
|
|
101
|
+
> **Prompt:** "I want to add a new predicate. Walk me through every file I need to update."
|
|
102
|
+
|
|
103
|
+
| | Without Memory | With Memory |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| **Response** | 6 steps targeting 3 **non-existent files** (`predicate.rb`, `predicate_synonyms.rb`, `json_schema.rb`) | 8 steps, all targeting **real files** with correct paths |
|
|
106
|
+
| **Outcome** | Plausible but wrong — would waste developer time | Actionable, correct, references actual commits |
|
|
107
|
+
|
|
108
|
+
### Cross-Project Preferences
|
|
109
|
+
|
|
110
|
+
> **Prompt:** "What are my standard development environment preferences across all my projects?"
|
|
111
|
+
|
|
112
|
+
| | Without Memory | With Memory |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| **Response** | "I don't have stored knowledge of your preferences" | Lists 7 real preferences: iTerm2, tmux, VS Code, PostgreSQL, Redis, Docker |
|
|
115
|
+
| **Outcome** | Blank slate every session | Personalized from day one |
|
|
116
|
+
|
|
117
|
+
### When Memory Doesn't Help
|
|
118
|
+
|
|
119
|
+
File-searchable questions ("what version is this?") and one-shot code generation without explicit recall don't benefit — `grep` is equally effective. Memory shines when the answer **isn't in any single file**: architecture spanning dozens of classes, conventions from past sessions, decisions with rationale, and user preferences.
|
|
120
|
+
|
|
86
121
|
## How It Works
|
|
87
122
|
|
|
88
123
|
1. **You chat with Claude** - Tell it about your project
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Migration v13: Add mcp_tool_calls telemetry table
|
|
4
|
+
# Records every MCP server tool invocation for usage stats and ROI tracking.
|
|
5
|
+
# Distinct from `tool_calls` (v3), which stores Claude Code tool observations
|
|
6
|
+
# extracted from transcripts.
|
|
7
|
+
Sequel.migration do
|
|
8
|
+
up do
|
|
9
|
+
create_table?(:mcp_tool_calls) do
|
|
10
|
+
primary_key :id
|
|
11
|
+
String :tool_name, null: false
|
|
12
|
+
String :called_at, null: false
|
|
13
|
+
Integer :duration_ms, null: false
|
|
14
|
+
Integer :result_count
|
|
15
|
+
String :scope
|
|
16
|
+
String :error_class
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
run "CREATE INDEX IF NOT EXISTS idx_mcp_tool_calls_name_time ON mcp_tool_calls(tool_name, called_at)"
|
|
20
|
+
run "CREATE INDEX IF NOT EXISTS idx_mcp_tool_calls_called_at ON mcp_tool_calls(called_at)"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
down do
|
|
24
|
+
drop_table?(:mcp_tool_calls)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Migration v14: Canonicalize stale predicate names in existing facts.
|
|
4
|
+
#
|
|
5
|
+
# The predicate vocabulary was curated in 0.9.0 — synonym canonicalization
|
|
6
|
+
# now runs at insert time (Resolver), but existing facts with stale
|
|
7
|
+
# predicate names need a one-time rewrite so they appear in the correct
|
|
8
|
+
# snapshot sections and query results.
|
|
9
|
+
#
|
|
10
|
+
# This migration applies PredicatePolicy::SYNONYMS to all active facts.
|
|
11
|
+
# Reversible: the down migration is a no-op because we can't know the
|
|
12
|
+
# original predicate name after rewriting.
|
|
13
|
+
Sequel.migration do
|
|
14
|
+
up do
|
|
15
|
+
# Inline the synonym map so the migration is self-contained and
|
|
16
|
+
# doesn't break if PredicatePolicy::SYNONYMS changes later.
|
|
17
|
+
synonyms = {
|
|
18
|
+
"has_convention" => "convention",
|
|
19
|
+
"primary_language" => "uses_language"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
synonyms.each do |from, to|
|
|
23
|
+
self[:facts].where(predicate: from).update(predicate: to)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
down do
|
|
28
|
+
# No-op: can't reverse a predicate rename without storing the original.
|
|
29
|
+
end
|
|
30
|
+
end
|
data/docs/improvements.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Improvements to Consider
|
|
2
2
|
|
|
3
|
-
*Updated: 2026-03-
|
|
3
|
+
*Updated: 2026-03-30 - Re-studied all 7 influencer repos. New recommendations: CLAUDE_CONFIG_DIR support (#26, from episodic-memory), Usage Stats / ROI Tracking (#27, from grepai v0.35.0). New Features to Avoid: AST-Aware Code Chunking (QMD), Custom Instructions via Env Var (lossless-claw v0.5.2), OpenClaw Context Injection (claude-mem v10.6.0). Repos with no changes: kbs (v0.2.1), claude-supermemory (v2.0.1), episodic-memory (v1.0.15). Previously: 14 features implemented through 2026-03-24.*
|
|
4
4
|
*Sources:*
|
|
5
|
-
- *[thedotmack/claude-mem](https://github.com/thedotmack/claude-mem) - Memory compression system (v10.
|
|
6
|
-
- *[obra/episodic-memory](https://github.com/obra/episodic-memory) - Semantic conversation search (v1.0.15, studied 2026-03-
|
|
7
|
-
- *[yoanbernabeu/grepai](https://github.com/yoanbernabeu/grepai) - Semantic code search (
|
|
8
|
-
- *[supermemoryai/claude-supermemory](https://github.com/supermemoryai/claude-supermemory) - Cloud-backed persistent memory (v2.0.1, studied 2026-03-
|
|
9
|
-
- *[tobi/qmd](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1, studied 2026-03-
|
|
10
|
-
- *[MadBomber/kbs](https://github.com/MadBomber/kbs) - Knowledge-Based System with RETE inference (v0.2.1, studied 2026-03-
|
|
11
|
-
- *[martian-engineering/lossless-claw](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.
|
|
5
|
+
- *[thedotmack/claude-mem](https://github.com/thedotmack/claude-mem) - Memory compression system (v10.6.3, re-studied 2026-03-30)*
|
|
6
|
+
- *[obra/episodic-memory](https://github.com/obra/episodic-memory) - Semantic conversation search (v1.0.15, re-studied 2026-03-30 — no changes)*
|
|
7
|
+
- *[yoanbernabeu/grepai](https://github.com/yoanbernabeu/grepai) - Semantic code search (v0.35.0, re-studied 2026-03-30)*
|
|
8
|
+
- *[supermemoryai/claude-supermemory](https://github.com/supermemoryai/claude-supermemory) - Cloud-backed persistent memory (v2.0.1, re-studied 2026-03-30 — no changes)*
|
|
9
|
+
- *[tobi/qmd](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1+unreleased, re-studied 2026-03-30)*
|
|
10
|
+
- *[MadBomber/kbs](https://github.com/MadBomber/kbs) - Knowledge-Based System with RETE inference (v0.2.1, studied 2026-03-30 — no changes)*
|
|
11
|
+
- *[martian-engineering/lossless-claw](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.5.2, re-studied 2026-03-30)*
|
|
12
12
|
|
|
13
13
|
This document contains only unimplemented improvements. Completed items are removed.
|
|
14
14
|
|
|
@@ -128,10 +128,43 @@ Source: QMD study (updated 2026-03-02)
|
|
|
128
128
|
|
|
129
129
|
`--async` flag on hook ingest/sweep/publish subcommands. Fork+detach for non-blocking execution, fallback to sync when fork unavailable.
|
|
130
130
|
|
|
131
|
+
### ~~26. CLAUDE_CONFIG_DIR Support~~ ✅ Implemented 2026-04-13
|
|
132
|
+
|
|
133
|
+
`Configuration#claude_config_dir` reads `CLAUDE_CONFIG_DIR` env var before falling back to `~/.claude`. `global_db_path` routes through it, so users with non-standard Claude Code config locations (or multiple profiles) can point the global memory DB anywhere without touching project DB resolution.
|
|
134
|
+
|
|
135
|
+
### 28. Code-Aware Transcript Chunking
|
|
136
|
+
|
|
137
|
+
Source: QMD v2.0.1+unreleased re-study (2026-03-30)
|
|
138
|
+
|
|
139
|
+
- **Value**: Better embeddings for transcripts containing code — detect fenced code blocks and apply AST-aware break points (function/class/import boundaries) rather than naive text splitting
|
|
140
|
+
- **Implementation**: Detect ` ```language ` fences in transcript content, parse code blocks with tree-sitter (via ruby_tree_sitter gem or shelling out), score break points (class=100, func=90, type=80, import=60), merge with markdown break points from #22
|
|
141
|
+
- **Evidence**: QMD `src/ast.ts` (392 lines) — web-tree-sitter with WASM grammars, `mergeBreakPoints()` combining AST + regex scores, graceful degradation on parse failure
|
|
142
|
+
- **Consideration**: Only useful in combination with #22 (Document Chunking). Transcripts often contain significant code in tool_use results and assistant responses
|
|
143
|
+
- **Effort**: 2-3 days (after #22)
|
|
144
|
+
- **Trade-off**: Adds tree-sitter dependency; graceful fallback to regex-only chunking when grammar unavailable
|
|
145
|
+
|
|
146
|
+
### 30. Predicate Census Command
|
|
147
|
+
|
|
148
|
+
Source: predicate retrospective (2026-04-15)
|
|
149
|
+
|
|
150
|
+
- **Value**: Aggregate predicate usage data across many project databases for informed vocabulary decisions — without exposing content. Enables data-sharing across machines (work/personal) via a privacy-safe JSON report.
|
|
151
|
+
- **Implementation**: `claude-memory census [--root ~/src]`. Finds all `.claude/memory.sqlite3` files under root, opens each read-only, collects per-DB predicate × status counts, entity type counts, schema version, novel predicates, synonym canonicalization candidates. Outputs aggregated JSON with **no object_literal, no entity names, no project paths, no quotes** — only schema-level signal.
|
|
152
|
+
- **Evidence**: The multi-project survey that caught the `uses_framework` cardinality bug (commit `29818c2`) was a manual bash loop. Productizing it means any user can contribute usage data for vocabulary curation without privacy risk.
|
|
153
|
+
- **Effort**: 0.5 days
|
|
154
|
+
- **Trade-off**: None — purely additive, read-only, privacy-safe by design
|
|
155
|
+
|
|
156
|
+
### ~~27. Usage Stats / ROI Tracking~~ ✅ Implemented 2026-04-15
|
|
157
|
+
|
|
158
|
+
Schema migration v13 adds `mcp_tool_calls` telemetry table (tool_name, called_at, duration_ms, result_count, scope, error_class). `MCP::Telemetry` wraps `Server#handle_tools_call` with monotonic-clock timing, captures errors, and records to the project DB; DB errors are swallowed so telemetry never fails a real tool call. `StatsCommand` gains `--tools` and `--since DAYS` flags showing total calls, error rate, and per-tool breakdown (calls, avg ms, p95 ms, error rate). `Sweep::Maintenance#prune_old_mcp_tool_calls` enforces a 90-day retention window, wired into `Sweeper#run!`. Rejected NDJSON in favor of SQLite for schema/query consistency with the rest of the gem. Dropped query-text capture (YAGNI — the dedup insight the hash would enable also needs raw text). Also fixed a latent bug where `StatsCommand` opened the DB via `Sequel.sqlite` (requiring the unlisted `sqlite3` gem); now uses the extralite adapter consistently.
|
|
159
|
+
|
|
131
160
|
---
|
|
132
161
|
|
|
133
162
|
## Low Priority / Defer
|
|
134
163
|
|
|
164
|
+
### ~~29. Derive CompletionCommand Descriptions from Registry~~ ✅ Implemented 2026-04-15
|
|
165
|
+
|
|
166
|
+
`Registry::COMMANDS` now stores `{class:, description:}` entries as the single source of truth. New `Registry.description` and `Registry.descriptions` accessors. `CompletionCommand` reads descriptions via `Registry.descriptions` instead of maintaining its own parallel hash. `Registry.find` also simplified — class references stored directly since command files are required before the Registry, eliminating `const_get` string indirection. Drift between the command list and completion output is now impossible without a deliberate edit to a single file.
|
|
167
|
+
|
|
135
168
|
### 23. REST API Endpoint
|
|
136
169
|
|
|
137
170
|
Source: QMD v2.0.1 study (2026-03-10)
|
|
@@ -219,6 +252,11 @@ Added `claude-memory export` command. Dumps facts with entities and provenance t
|
|
|
219
252
|
- **Sub-Agent Delegation for Deep Recall** — lossless-claw spawns sub-agents for DAG traversal. Adds latency and complexity; our direct MCP tool responses are simpler and faster
|
|
220
253
|
- **Message Parts Polymorphism** — lossless-claw's 10-column message_parts for tool calls, reasoning, patches. We don't store raw messages, so irrelevant
|
|
221
254
|
- **OpenClaw ContextEngine Interface** — Tight framework coupling. Our MCP + hooks approach is more portable
|
|
255
|
+
- **Chunk Strategy Option** — QMD's `--chunk-strategy auto` for code files. ClaudeMemory has no standalone chunking pipeline to configure (QMD v0.35.0)
|
|
256
|
+
- **Custom Instructions via Env Var** — lossless-claw's `LCM_CUSTOM_INSTRUCTIONS` config stub exists but is never wired to summarization prompts. Incomplete pattern; our skill-based prompts are better (lossless-claw v0.5.2)
|
|
257
|
+
- **OpenClaw Context Injection** — claude-mem v10.6.0's `appendSystemContext` with 60s cache replaces MEMORY.md writes. Our SessionStart hook context injection already does this (claude-mem v10.6.0)
|
|
258
|
+
- **Message Parts Polymorphism** — lossless-claw's 10-column message_parts for tool calls, reasoning, patches. We don't store raw messages, so irrelevant
|
|
259
|
+
- **OpenClaw ContextEngine Interface** — Tight framework coupling. Our MCP + hooks approach is more portable
|
|
222
260
|
|
|
223
261
|
---
|
|
224
262
|
|
|
@@ -241,22 +279,22 @@ Added `claude-memory export` command. Dumps facts with entities and provenance t
|
|
|
241
279
|
## References
|
|
242
280
|
|
|
243
281
|
- [episodic-memory GitHub](https://github.com/obra/episodic-memory) - Semantic conversation search (v1.0.15)
|
|
244
|
-
- [claude-mem GitHub](https://github.com/thedotmack/claude-mem) - Memory compression system (v10.
|
|
245
|
-
- [grepai GitHub](https://github.com/yoanbernabeu/grepai) - Semantic code search (
|
|
282
|
+
- [claude-mem GitHub](https://github.com/thedotmack/claude-mem) - Memory compression system (v10.6.3)
|
|
283
|
+
- [grepai GitHub](https://github.com/yoanbernabeu/grepai) - Semantic code search (v0.35.0)
|
|
246
284
|
- [claude-supermemory GitHub](https://github.com/supermemoryai/claude-supermemory) - Cloud-backed memory (v2.0.1)
|
|
247
|
-
- [QMD GitHub](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1)
|
|
285
|
+
- [QMD GitHub](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1+unreleased)
|
|
248
286
|
- [KBS GitHub](https://github.com/MadBomber/kbs) - Knowledge-Based System with RETE inference (v0.2.1)
|
|
249
|
-
- [lossless-claw GitHub](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.
|
|
287
|
+
- [lossless-claw GitHub](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.5.2)
|
|
250
288
|
|
|
251
289
|
Influence documents:
|
|
252
|
-
- [docs/influence/qmd.md](influence/qmd.md) -
|
|
253
|
-
- [docs/influence/episodic-memory.md](influence/episodic-memory.md) -
|
|
254
|
-
- [docs/influence/claude-mem.md](influence/claude-mem.md) -
|
|
255
|
-
- [docs/influence/grepai.md](influence/grepai.md) -
|
|
256
|
-
- [docs/influence/claude-supermemory.md](influence/claude-supermemory.md) -
|
|
257
|
-
- [docs/influence/kbs.md](influence/kbs.md) -
|
|
258
|
-
- [docs/influence/lossless-claw.md](influence/lossless-claw.md) -
|
|
290
|
+
- [docs/influence/qmd.md](influence/qmd.md) - Re-studied 2026-03-30
|
|
291
|
+
- [docs/influence/episodic-memory.md](influence/episodic-memory.md) - Re-studied 2026-03-30
|
|
292
|
+
- [docs/influence/claude-mem.md](influence/claude-mem.md) - Re-studied 2026-03-30
|
|
293
|
+
- [docs/influence/grepai.md](influence/grepai.md) - Re-studied 2026-03-30
|
|
294
|
+
- [docs/influence/claude-supermemory.md](influence/claude-supermemory.md) - Re-studied 2026-03-30
|
|
295
|
+
- [docs/influence/kbs.md](influence/kbs.md) - Re-studied 2026-03-30 (no changes)
|
|
296
|
+
- [docs/influence/lossless-claw.md](influence/lossless-claw.md) - Re-studied 2026-03-30
|
|
259
297
|
|
|
260
298
|
---
|
|
261
299
|
|
|
262
|
-
*Last updated: 2026-
|
|
300
|
+
*Last updated: 2026-04-15 - Predicate retrospective: fixed uses_framework cardinality bug, curated vocabulary to 8 predicates, added synonym canonicalization + novel-predicate warnings. Also: reject/restore commands, #26 CLAUDE_CONFIG_DIR, #27 telemetry, #29 Registry descriptions.*
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*Analysis Date: 2026-03-02*
|
|
4
4
|
*Repository: https://github.com/thedotmack/claude-mem*
|
|
5
5
|
*Version: 10.5.2 (commit ecb09df)*
|
|
6
|
+
*Re-studied: 2026-03-30 — v10.6.3 (commit d068821). 4 releases since last study (v10.5.6, v10.6.0, v10.6.1, v10.6.2, v10.6.3). Key changes: OpenClaw system prompt context injection replacing MEMORY.md writes (v10.6.0), compressed context output ~53% smaller (v10.6.1), timeline report skill (v10.6.1), process supervisor hardening with PID 0 fix and signal race condition fix (v10.5.6), activity spinner orphan session fix (v10.6.2), Gemini CLI integration (v10.6.3), 7 critical cross-platform bug fixes (v10.6.3). Context injection pattern (appendSystemContext with 60s cache) aligns with our SessionStart hook approach. Compressed context format worth studying. No new adoptable patterns beyond what we already implement.*
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
*Analysis Date: 2026-03-02*
|
|
4
4
|
*Previous Analysis: 2026-02-02*
|
|
5
|
+
*Re-studied: 2026-03-30 — No meaningful code changes since v2.0.1. marketplace.json bumped to 0.0.3, added claude-code-review GitHub Action (anthropics/claude-code-action@v1). All findings remain current.*
|
|
5
6
|
*Repository: https://github.com/supermemoryai/claude-supermemory*
|
|
6
7
|
*Version: 2.0.0 (commit de39413)*
|
|
7
8
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*Analysis Date: 2026-03-02*
|
|
4
4
|
*Repository: https://github.com/obra/episodic-memory*
|
|
5
5
|
*Version: 1.0.15 (commit 6feaa5b)*
|
|
6
|
+
*Re-studied: 2026-03-30 — No changes since v1.0.15. Repo dormant. One adoptable pattern identified: CLAUDE_CONFIG_DIR env var support (`src/paths.ts:20-22`) for configurable Claude config directory. Orphaned MCP process prevention (SIGHUP handler in wrapper) not applicable — ClaudeMemory runs as single Ruby process, no wrapper/child architecture.*
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
data/docs/influence/grepai.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*Previous Analysis: 2026-01-29*
|
|
5
5
|
*Repository: https://github.com/yoanbernabeu/grepai*
|
|
6
6
|
*Version: 0.34.0 (commit 1c7aba9)*
|
|
7
|
+
*Re-studied: 2026-03-30 — v0.35.0. One release since last study (2026-03-16). Key addition: privacy-first usage stats tracking (`stats/` package) recording every search/trace to NDJSON file (`.grepai/stats.json`), computing output tokens vs grep-equivalent tokens with savings percentages and optional USD cost savings. Fire-and-forget recording via goroutine with 100ms timeout, file-locking for cross-process safety. Shell completion also added (we already have this via #18). `.grepaiignore` support not relevant.*
|
|
7
8
|
|
|
8
9
|
---
|
|
9
10
|
|
data/docs/influence/kbs.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*Analysis Date: 2026-03-16*
|
|
4
4
|
*Repository: https://github.com/martian-engineering/lossless-claw*
|
|
5
5
|
*Version: 0.3.0 (commit 49949fb)*
|
|
6
|
+
*Re-studied: 2026-03-30 — v0.5.2. 5 releases since last study. Core DAG architecture unchanged; changes are operational hardening. Custom Instructions (`LCM_CUSTOM_INSTRUCTIONS`) — config stub exists but never wired to summarization prompts, do not adopt. Session exclusion patterns (ignore + stateless) — clean implementation but low priority (we already have ContentSanitizer exclusion tags). Prompt Slot Pattern — does not exist in codebase, not applicable. New: CJK-aware FTS5 fallback with `icu` tokenizer detection worth considering. Also: provider auth error surfacing, summarizer timeouts, bootstrap checkpoints, Docker support, TUI doctor command.*
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
data/docs/influence/qmd.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*Previous Analysis: 2026-03-02, 2026-02-02*
|
|
5
5
|
*Repository: https://github.com/tobi/qmd*
|
|
6
6
|
*Version: 2.0.1 (commit ae3604c)*
|
|
7
|
+
*Re-studied: 2026-03-30 — v2.0.1+unreleased. One significant addition: AST-aware chunking (`src/ast.ts`, 392 lines) using web-tree-sitter with WASM grammars for TS/JS/Python/Go/Rust. Detects language from extension, parses AST, extracts break points at function/class/import boundaries (class=100, func=90, type=80, import=60). Merged with regex break points via `mergeBreakPoints()`. Opt-in via `--chunk-strategy auto`. While we ingest transcripts rather than source code, transcripts frequently contain embedded code in tool results and assistant responses. AST-aware break points could improve embedding quality for code-heavy transcripts when combined with Document Chunking (#22). Added as improvement #28 (Code-Aware Transcript Chunking).*
|
|
7
8
|
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -37,7 +37,7 @@ module ClaudeMemory
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def zsh_completion
|
|
40
|
-
commands_with_desc =
|
|
40
|
+
commands_with_desc = Registry.descriptions.sort.map { |name, desc|
|
|
41
41
|
" '#{name}:#{desc}'"
|
|
42
42
|
}.join("\n")
|
|
43
43
|
|
|
@@ -141,36 +141,6 @@ module ClaudeMemory
|
|
|
141
141
|
BASH
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
def command_descriptions
|
|
145
|
-
{
|
|
146
|
-
"changes" => "Show recent fact changes",
|
|
147
|
-
"compact" => "Compact databases",
|
|
148
|
-
"completion" => "Generate shell completions",
|
|
149
|
-
"conflicts" => "Show open conflicts",
|
|
150
|
-
"db:init" => "Initialize database",
|
|
151
|
-
"doctor" => "Check system health",
|
|
152
|
-
"explain" => "Explain a fact with receipts",
|
|
153
|
-
"export" => "Export facts to JSON",
|
|
154
|
-
"git-lfs" => "Git LFS integration",
|
|
155
|
-
"help" => "Show help message",
|
|
156
|
-
"hook" => "Run hook entrypoints",
|
|
157
|
-
"index" => "Index content",
|
|
158
|
-
"ingest" => "Ingest transcript delta",
|
|
159
|
-
"init" => "Initialize ClaudeMemory",
|
|
160
|
-
"install-skill" => "Install agent skills",
|
|
161
|
-
"promote" => "Promote fact to global",
|
|
162
|
-
"publish" => "Publish snapshot",
|
|
163
|
-
"recall" => "Recall facts matching query",
|
|
164
|
-
"recover" => "Recover database",
|
|
165
|
-
"search" => "Search indexed content",
|
|
166
|
-
"serve-mcp" => "Start MCP server",
|
|
167
|
-
"stats" => "Show statistics",
|
|
168
|
-
"sweep" => "Run maintenance",
|
|
169
|
-
"uninstall" => "Remove configuration",
|
|
170
|
-
"version" => "Show version"
|
|
171
|
-
}
|
|
172
|
-
end
|
|
173
|
-
|
|
174
144
|
def skill_names
|
|
175
145
|
InstallSkillCommand::AVAILABLE_SKILLS.keys
|
|
176
146
|
end
|