claude_memory 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/CLAUDE.md +1 -1
  3. data/.claude/rules/claude_memory.generated.md +1 -1
  4. data/.claude/settings.json +11 -6
  5. data/.claude/settings.local.json +9 -1
  6. data/.claude-plugin/marketplace.json +5 -2
  7. data/.claude-plugin/plugin.json +16 -3
  8. data/.mcp.json +9 -0
  9. data/CHANGELOG.md +69 -0
  10. data/CLAUDE.md +27 -13
  11. data/README.md +6 -2
  12. data/Rakefile +22 -0
  13. data/db/migrations/011_add_tool_call_summaries.rb +18 -0
  14. data/db/migrations/012_add_vec_indexing_support.rb +19 -0
  15. data/docs/improvements.md +86 -66
  16. data/docs/influence/claude-mem.md +253 -0
  17. data/docs/influence/claude-supermemory.md +158 -430
  18. data/docs/influence/episodic-memory.md +217 -0
  19. data/docs/influence/grepai.md +163 -839
  20. data/docs/influence/kbs.md +437 -0
  21. data/docs/influence/qmd.md +139 -481
  22. data/hooks/hooks.json +19 -15
  23. data/lefthook.yml +4 -0
  24. data/lib/claude_memory/commands/checks/vec_check.rb +73 -0
  25. data/lib/claude_memory/commands/compact_command.rb +94 -0
  26. data/lib/claude_memory/commands/doctor_command.rb +1 -0
  27. data/lib/claude_memory/commands/export_command.rb +108 -0
  28. data/lib/claude_memory/commands/help_command.rb +2 -0
  29. data/lib/claude_memory/commands/hook_command.rb +110 -9
  30. data/lib/claude_memory/commands/index_command.rb +63 -8
  31. data/lib/claude_memory/commands/initializers/global_initializer.rb +26 -7
  32. data/lib/claude_memory/commands/initializers/project_initializer.rb +35 -12
  33. data/lib/claude_memory/commands/registry.rb +3 -1
  34. data/lib/claude_memory/hook/context_injector.rb +75 -0
  35. data/lib/claude_memory/hook/error_classifier.rb +67 -0
  36. data/lib/claude_memory/hook/handler.rb +21 -1
  37. data/lib/claude_memory/index/vector_index.rb +171 -0
  38. data/lib/claude_memory/infrastructure/schema_validator.rb +5 -1
  39. data/lib/claude_memory/ingest/ingester.rb +26 -1
  40. data/lib/claude_memory/ingest/observation_compressor.rb +177 -0
  41. data/lib/claude_memory/mcp/instructions_builder.rb +76 -0
  42. data/lib/claude_memory/mcp/server.rb +3 -1
  43. data/lib/claude_memory/mcp/tool_definitions.rb +15 -7
  44. data/lib/claude_memory/mcp/tools.rb +125 -2
  45. data/lib/claude_memory/publish.rb +28 -27
  46. data/lib/claude_memory/recall/dual_query_template.rb +1 -12
  47. data/lib/claude_memory/recall.rb +71 -17
  48. data/lib/claude_memory/store/sqlite_store.rb +95 -29
  49. data/lib/claude_memory/sweep/sweeper.rb +30 -0
  50. data/lib/claude_memory/version.rb +1 -1
  51. data/lib/claude_memory.rb +8 -0
  52. data/scripts/hook-runner.sh +14 -0
  53. data/scripts/serve-mcp.sh +14 -0
  54. data/skills/setup-memory/SKILL.md +6 -0
  55. metadata +32 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d32c7aa8093eedade1783eefa7109c996aa134d01dea01b67794612c126cf068
4
- data.tar.gz: 78fe0f2ff602c740b6ab727a0fde88d07fb235f38b1143b644b4e7498f07079f
3
+ metadata.gz: 28dba99c7b0ed1cb18bdc6f8ff8c2a12e86f3b89be8cfbc2055f7d4dd82c8250
4
+ data.tar.gz: a40e938d1ceab94a386a3f676f6d56cbfa5914b8940ac8ca6165a551b5ff090d
5
5
  SHA512:
6
- metadata.gz: be68b153e9e25ef3b8e5ad71ba7fdd89e5ace40f0848125b480bf35c96ad8b0a73b1fd891e59faf5807bc99d8d637f0c6d647e2b1d6c86ad0654b9df69c1ab45
7
- data.tar.gz: 92ee3e92e7967e03f642a5736a84f70563dd6e9f00fc3a7b24714b97294348e35645cdbfdd4b760bc5ee21301bb869bccbc686050cbc95e2bf7399c38508a32e
6
+ metadata.gz: 6575064801648828b09cc17db9413d339c46767e27b9510e0b877c5e877c452ce142c9082459af5315dd4dbf516360ea73a3b23295603304454b171ba70798b1
7
+ data.tar.gz: d2841200827478e8e4dd2f6a3a2575541138ed3bf673e0f9d633d771363355bb95c2adf0c677a104022175769af04973543cce65f81223a736eba7c3630ca3d9
data/.claude/CLAUDE.md CHANGED
@@ -1,4 +1,4 @@
1
- <!-- ClaudeMemory v0.5.0 -->
1
+ <!-- ClaudeMemory v0.6.0 -->
2
2
  # Project Memory
3
3
 
4
4
  @.claude/rules/claude_memory.generated.md
@@ -1,7 +1,7 @@
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-02-04T16:37:00Z
4
+ Generated: 2026-02-05T18:27:44Z
5
5
  -->
6
6
 
7
7
  # Project Memory
@@ -5,7 +5,7 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
8
+ "command": "claude-memory hook ingest",
9
9
  "timeout": 10
10
10
  }
11
11
  ]
@@ -16,8 +16,13 @@
16
16
  "hooks": [
17
17
  {
18
18
  "type": "command",
19
- "command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
19
+ "command": "claude-memory hook ingest",
20
20
  "timeout": 10
21
+ },
22
+ {
23
+ "type": "command",
24
+ "command": "claude-memory hook context",
25
+ "timeout": 5
21
26
  }
22
27
  ]
23
28
  }
@@ -27,12 +32,12 @@
27
32
  "hooks": [
28
33
  {
29
34
  "type": "command",
30
- "command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
35
+ "command": "claude-memory hook ingest",
31
36
  "timeout": 30
32
37
  },
33
38
  {
34
39
  "type": "command",
35
- "command": "claude-memory hook sweep --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
40
+ "command": "claude-memory hook sweep",
36
41
  "timeout": 30
37
42
  }
38
43
  ]
@@ -43,12 +48,12 @@
43
48
  "hooks": [
44
49
  {
45
50
  "type": "command",
46
- "command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
51
+ "command": "claude-memory hook ingest",
47
52
  "timeout": 30
48
53
  },
49
54
  {
50
55
  "type": "command",
51
- "command": "claude-memory hook sweep --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
56
+ "command": "claude-memory hook sweep",
52
57
  "timeout": 30
53
58
  }
54
59
  ]
@@ -28,7 +28,15 @@
28
28
  "mcp__plugin_claude-memory_memory__memory_architecture",
29
29
  "mcp__plugin_claude-memory_memory__memory_recall_index",
30
30
  "Bash(./bin/run-evals:*)",
31
- "WebSearch"
31
+ "WebSearch",
32
+ "mcp__memory__memory_check_setup",
33
+ "WebFetch(domain:docs.anthropic.com)",
34
+ "Bash(export PATH=\"$HOME/.bun/bin:/usr/bin:/bin:$PATH\")",
35
+ "Bash(qmd search:*)",
36
+ "Skill(study-repo)",
37
+ "WebFetch(domain:www.rubydoc.info)",
38
+ "Bash(git status:*)",
39
+ "WebFetch(domain:github.com)"
32
40
  ]
33
41
  },
34
42
  "enableAllProjectMcpServers": true
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "claude-memory-marketplace",
3
3
  "owner": {
4
- "name": "Valentino Stoll"
4
+ "name": "Valentino Stoll",
5
+ "email": "v@codenamev.com"
5
6
  },
6
7
  "plugins": [
7
8
  {
8
9
  "name": "claude-memory",
10
+ "version": "0.6.0",
9
11
  "source": "./",
10
- "description": "Long-term self-managed memory for Claude Code"
12
+ "description": "Long-term self-managed memory for Claude Code with fact extraction, truth maintenance, and provenance tracking",
13
+ "repository": "https://github.com/codenamev/claude_memory"
11
14
  }
12
15
  ]
13
16
  }
@@ -1,10 +1,23 @@
1
1
  {
2
2
  "name": "claude-memory",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Long-term self-managed memory for Claude Code with fact extraction, truth maintenance, and provenance tracking",
5
5
  "author": {
6
- "name": "Valentino Stoll"
6
+ "name": "Valentino Stoll",
7
+ "email": "v@codenamev.com"
7
8
  },
9
+ "homepage": "https://github.com/codenamev/claude_memory",
10
+ "repository": "https://github.com/codenamev/claude_memory",
8
11
  "license": "MIT",
9
- "keywords": ["memory", "facts", "knowledge", "persistence"]
12
+ "keywords": ["memory", "facts", "knowledge", "persistence", "long-term-memory"],
13
+ "mcpServers": {
14
+ "memory": {
15
+ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/serve-mcp.sh",
16
+ "args": []
17
+ }
18
+ },
19
+ "hooks": "./hooks/hooks.json",
20
+ "skills": "./skills/",
21
+ "commands": "./commands/",
22
+ "outputStyles": "./output-styles/"
10
23
  }
data/.mcp.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "mcpServers": {
3
+ "memory": {
4
+ "type": "stdio",
5
+ "command": "claude-memory",
6
+ "args": ["serve-mcp"]
7
+ }
8
+ }
9
+ }
data/CHANGELOG.md CHANGED
@@ -4,6 +4,75 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.6.0] - 2026-03-06
8
+
9
+ ### Added
10
+
11
+ **Native Vector Storage (sqlite-vec)**
12
+ - Integrated [sqlite-vec](https://github.com/asg017/sqlite-vec) for native KNN vector search
13
+ - `VectorIndex` class with vec0 virtual table for cosine similarity search
14
+ - Dual-write: embeddings stored in both JSON column and vec0 index
15
+ - `claude-memory index --vec` flag for backfilling existing embeddings into vec0
16
+ - Fast path in `Recall` uses sqlite-vec KNN when available, falls back to JSON + Ruby
17
+ - Sweeper cleans up vec0 entries for superseded/expired facts
18
+ - Doctor and MCP status/stats report vec0 availability and coverage
19
+ - Cross-platform support with platform-specific gem installation
20
+
21
+ **Database Maintenance**
22
+ - `compact` command for database maintenance (VACUUM + integrity check)
23
+ - `export` command for fact backup and migration to JSON
24
+
25
+ **Hook Enhancements**
26
+ - SessionStart context injection via `hookSpecificOutput.additionalContext`
27
+ - Injects recent facts and project context at session start
28
+ - Tool-specific observation compression for reduced token usage
29
+ - `--async` flag for non-blocking hook execution
30
+ - Hook error classification for graceful degradation
31
+ - Conversation exclusion markers for session-level opt-out
32
+
33
+ **MCP Discovery**
34
+ - `memory.list_projects` MCP tool for discovering all project databases
35
+
36
+ **Developer Experience**
37
+ - Dynamic MCP server instructions with progressive disclosure documentation
38
+ - Comparative benchmark suite with QMD and grepai adapters
39
+ - `bin/setup-competitors` for installing competitor tools
40
+ - `bin/run-evals --comparative` for side-by-side benchmarks
41
+
42
+ ### Fixed
43
+
44
+ - **Recall returned no results**: `DualQueryTemplate` accessed stores before initializing them,
45
+ causing all recall queries to silently return empty results. Refactored to use existing
46
+ `store_for_scope` method which handles initialization and access atomically.
47
+ - **Doctor crashed on sqlite-vec tables**: `SchemaValidator` iterated all tables including vec0
48
+ virtual tables, which require the sqlite-vec extension. Now skips `facts_vec*` tables using
49
+ prefix match to handle future partition tables.
50
+ - **Forward-migrated databases**: Older gem versions now gracefully handle databases migrated
51
+ by newer versions instead of crashing.
52
+ - **Hybrid retrieval ordering**: Preserved BM25 scores and RRF ordering in hybrid search results
53
+ instead of re-sorting by source/time.
54
+ - Fork-based concurrency tests skipped on Ruby 4.0+ (Extralite incompatibility)
55
+ - Real eval tests now run in tmpdir with fixture database
56
+
57
+ ### Internal
58
+ - Refactored publish to avoid unnecessary rewrites from timestamp churn
59
+ - Skip quality-review hook when running inside Claude Code session
60
+ - Influence studies for claude-mem, episodic-memory, kbs repositories
61
+
62
+ ## [0.5.1] - 2026-02-04
63
+
64
+ ### Fixed
65
+
66
+ - **Database Lock Errors**: Fixed "database is locked" and "database is busy" errors when
67
+ multiple Claude Code hooks run concurrently
68
+ - Added application-level retry with exponential backoff (5 retries, 0.1s base delay)
69
+ - Reduced SQLite busy_timeout from 30s to 1s for faster failure detection
70
+ - Added `with_retry` and `transaction_with_retry` methods for concurrent access handling
71
+ - SQLite's busy_timeout doesn't reliably detect lock release; app-level retry compensates
72
+
73
+ - **MCP Server Auto-Registration**: Added `.mcp.json` at plugin root so MCP server is
74
+ automatically registered when plugin is installed (previously only worked in dev directory)
75
+
7
76
  ## [0.5.0] - 2026-02-04
8
77
 
9
78
  ### Added
data/CLAUDE.md CHANGED
@@ -87,6 +87,16 @@ EVAL_MODE=real bundle exec rspec spec/benchmarks/e2e/ --tag eval_real
87
87
 
88
88
  DevMemBench measures retrieval accuracy (Recall@k, MRR, nDCG@10) across 155 queries, truth maintenance correctness across 100 cases, and end-to-end Claude response quality across 31 scenarios. Semantic and hybrid retrieval use [fastembed-rb](https://github.com/khasinski/fastembed-rb) (BAAI/bge-small-en-v1.5, local ONNX, no API key). See `spec/benchmarks/README.md` for full details.
89
89
 
90
+ ### Comparative Benchmarks
91
+ ```bash
92
+ bin/setup-competitors # Install QMD + grepai + dependencies (~3GB)
93
+ bin/setup-competitors --check # Show what's installed
94
+ bin/setup-competitors --qmd-only # Only install QMD + Bun
95
+ bin/setup-competitors --grepai-only # Only install grepai + Ollama
96
+ bin/run-evals --comparative # Run benchmarks with available tools
97
+ bin/run-evals --comparative --setup-competitors # Install + run in one step
98
+ ```
99
+
90
100
  ## Architecture
91
101
 
92
102
  ### Dual-Database System
@@ -160,7 +170,9 @@ Transcripts → Ingest → Index (FTS5)
160
170
  - **`Ingest`**: Transcript reading and delta-based ingestion (`ingest/`)
161
171
  - Tracks cursor position per session to avoid re-processing
162
172
 
163
- - **`Index`**: Full-text search using SQLite FTS5 (`index/`)
173
+ - **`Index`**: Full-text search and vector indexing (`index/`)
174
+ - `LexicalFTS`: SQLite FTS5 full-text search
175
+ - `VectorIndex`: sqlite-vec native KNN search with vec0 virtual tables
164
176
  - Optimized with batch queries to eliminate N+1 issues
165
177
 
166
178
  - **`Distill`**: Fact extraction interface (`distill/`)
@@ -184,8 +196,8 @@ Transcripts → Ingest → Index (FTS5)
184
196
  - Modes: shared (repo), local (uncommitted), home (user directory)
185
197
 
186
198
  - **`MCP`**: Model Context Protocol server and tools (`mcp/`)
187
- - Exposes memory tools to Claude Code
188
- - Tools: recall, explain, promote, status, conflicts, changes, sweep_now
199
+ - Exposes memory tools to Claude Code (21 tools total)
200
+ - Dual content/structuredContent responses with compact mode
189
201
 
190
202
  - **`Hook`**: Hook entrypoint handlers (`hook/`)
191
203
  - Reads stdin JSON from Claude Code hooks
@@ -274,7 +286,7 @@ Single-value predicates (like "uses_database") supersede old values. Multi-value
274
286
 
275
287
  - `lib/claude_memory.rb`: Main module, requires, database path helpers
276
288
  - `lib/claude_memory/cli.rb`: Thin command router (41 lines)
277
- - `lib/claude_memory/commands/`: Individual command classes (20 commands)
289
+ - `lib/claude_memory/commands/`: Individual command classes (22 commands)
278
290
  - `lib/claude_memory/configuration.rb`: Centralized configuration and ENV access
279
291
  - `lib/claude_memory/domain/`: Domain models (Fact, Entity, Provenance, Conflict)
280
292
  - `lib/claude_memory/core/`: Value objects and null objects
@@ -289,31 +301,33 @@ Single-value predicates (like "uses_database") supersede old values. Multi-value
289
301
 
290
302
  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.
291
303
 
292
- Available MCP tools (18 total):
304
+ Available MCP tools (21 total):
293
305
  - **Query & Recall**: `memory.recall`, `memory.recall_index`, `memory.recall_details`, `memory.recall_semantic`, `memory.search_concepts`
294
- - **Provenance**: `memory.explain`
306
+ - **Provenance**: `memory.explain`, `memory.fact_graph`
295
307
  - **Shortcuts**: `memory.decisions`, `memory.conventions`, `memory.architecture`
296
308
  - **Context**: `memory.facts_by_tool`, `memory.facts_by_context`
297
309
  - **Management**: `memory.promote`, `memory.store_extraction`
298
310
  - **Monitoring**: `memory.status`, `memory.stats`, `memory.changes`, `memory.conflicts`
299
311
  - **Maintenance**: `memory.sweep_now`
300
- - **Setup**: `memory.check_setup`
312
+ - **Discovery**: `memory.check_setup`, `memory.list_projects`
301
313
 
302
314
  ## Hook Integration
303
315
 
304
316
  ClaudeMemory integrates with Claude Code via hooks in `.claude/settings.json`:
305
317
 
306
- - **Ingest hook**: Triggers on Stop/SessionStart/PreCompact events
318
+ - **Ingest hook**: Triggers on Stop/SessionStart/PreCompact/SessionEnd events
307
319
  - Calls `claude-memory hook ingest` with stdin JSON
308
320
  - Reads transcript delta and updates both global and project databases
309
321
 
310
- - **Sweep hook**: Triggers on idle_prompt and safety events
311
- - Runs time-bounded maintenance on both databases
322
+ - **Context hook**: Triggers on SessionStart
323
+ - Calls `claude-memory hook context`
324
+ - Injects recent facts via `hookSpecificOutput.additionalContext`
312
325
 
313
- - **Publish hook**: Optional, on SessionEnd/PreCompact
314
- - Publishes curated snapshot to `.claude/rules/`
326
+ - **Sweep hook**: Triggers on PreCompact/SessionEnd events
327
+ - Runs time-bounded maintenance on both databases
328
+ - Cleans up vec0 entries for superseded/expired facts
315
329
 
316
- Hook commands read JSON payloads from stdin for robustness.
330
+ Hook commands read JSON payloads from stdin for robustness. Supports `--async` flag for non-blocking execution.
317
331
 
318
332
  ## Code Style
319
333
 
data/README.md CHANGED
@@ -95,12 +95,16 @@ Claude: "Based on my memory, you're using Rails with PostgreSQL..."
95
95
  ## Key Features
96
96
 
97
97
  - **Dual Scope**: Project-specific + global user preferences
98
+ - **Hybrid Search**: FTS5 full-text + semantic vector search with Reciprocal Rank Fusion
99
+ - **Native Vector Storage**: [sqlite-vec](https://github.com/asg017/sqlite-vec) for fast KNN search with local embeddings ([fastembed-rb](https://github.com/khasinski/fastembed-rb), no API key)
100
+ - **Session Context**: Automatic context injection at session start with recent facts
98
101
  - **Privacy First**: `<private>` tags exclude sensitive data
99
102
  - **Progressive Disclosure**: Lightweight queries before full details
100
103
  - **Semantic Shortcuts**: Quick access to decisions, conventions, architecture
101
104
  - **Truth Maintenance**: Automatic conflict resolution
102
105
  - **Claude-Powered**: Uses Claude's intelligence to extract facts (no API key needed)
103
106
  - **Token Efficient**: 10x reduction in memory queries with progressive disclosure
107
+ - **Database Maintenance**: Compact, export, and backup commands
104
108
 
105
109
  ## Privacy Control
106
110
 
@@ -169,10 +173,10 @@ claude-memory doctor
169
173
  This checks:
170
174
  - Database existence and integrity
171
175
  - Schema version compatibility
176
+ - sqlite-vec availability and index coverage
172
177
  - Hooks configuration
173
178
  - Snapshot status
174
179
  - Stuck operations
175
- - Orphaned hooks (hooks without MCP configuration)
176
180
 
177
181
  ### Uninstalling
178
182
 
@@ -253,7 +257,7 @@ The benchmark dataset draws from real CLAUDE.md patterns and is designed specifi
253
257
 
254
258
  - **Language:** Ruby 3.2+
255
259
  - **Storage:** SQLite3 (no external services)
256
- - **Testing:** 985 examples, 100% core coverage
260
+ - **Testing:** 1316 examples, 100% core coverage
257
261
  - **Code Style:** Standard Ruby
258
262
 
259
263
  ```bash
data/Rakefile CHANGED
@@ -20,4 +20,26 @@ RSpec::Core::RakeTask.new(:spec_sequential)
20
20
 
21
21
  require "standard/rake"
22
22
 
23
+ namespace :plugin do
24
+ desc "Sync ClaudeMemory::VERSION into .claude-plugin/plugin.json and marketplace.json"
25
+ task :sync_version do
26
+ require_relative "lib/claude_memory/version"
27
+ version = ClaudeMemory::VERSION
28
+
29
+ %w[.claude-plugin/plugin.json .claude-plugin/marketplace.json].each do |path|
30
+ next unless File.exist?(path)
31
+
32
+ content = File.read(path)
33
+ updated = content.gsub(/"version"\s*:\s*"[^"]*"/, "\"version\": \"#{version}\"")
34
+
35
+ if content != updated
36
+ File.write(path, updated)
37
+ puts "Updated #{path} to version #{version}"
38
+ else
39
+ puts "#{path} already at version #{version}"
40
+ end
41
+ end
42
+ end
43
+ end
44
+
23
45
  task default: %i[spec standard]
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Migration v11: Add compressed_summary to tool_calls
4
+ # Stores human-readable summaries of tool observations
5
+ # e.g., "Edited auth.rb: 'def login' → 'def async_login'"
6
+ Sequel.migration do
7
+ up do
8
+ alter_table(:tool_calls) do
9
+ add_column :compressed_summary, String, text: true
10
+ end
11
+ end
12
+
13
+ down do
14
+ alter_table(:tool_calls) do
15
+ drop_column :compressed_summary
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Migration v12: Add vec_indexed_at tracking column to facts
4
+ # Tracks which facts have been populated in the facts_vec virtual table.
5
+ # The facts_vec virtual table itself is created lazily at runtime
6
+ # because the sqlite-vec extension must be loaded before CREATE VIRTUAL TABLE.
7
+ Sequel.migration do
8
+ up do
9
+ alter_table(:facts) do
10
+ add_column :vec_indexed_at, String, text: true
11
+ end
12
+ end
13
+
14
+ down do
15
+ alter_table(:facts) do
16
+ drop_column :vec_indexed_at
17
+ end
18
+ end
19
+ end