# v0.18.0 Phase 1 — Changes Guide ## New Files (drop in place) | File | Description | |------|-------------| | `server/database/migrations/004_v0180_memories.sql` | Postgres migration — memories table, indexes, trigger | | `server/database/migrations/sqlite/003_v0180_memories.sql` | SQLite equivalent | | `server/models/models_memory.go` | Memory + MemoryFilter model structs + scope/status constants | | `server/store/store_memory.go` | MemoryStore interface definition | | `server/store/postgres/memory.go` | Postgres MemoryStore implementation | | `server/store/sqlite/memory.go` | SQLite MemoryStore implementation | | `server/tools/memory.go` | memory_save + memory_recall tools with late registration | | `server/handlers/memory_inject.go` | BuildMemoryHint() for context injection | | `docs/DESIGN-0.18.0.md` | Design document | ## Existing File Modifications ### 1. `server/store/interfaces.go` Add to the `Stores` struct (after `ResourceGrants`): ```go Memories MemoryStore ``` The `MemoryStore` interface itself is in the new `store_memory.go` file (same package, separate file for cleanliness). ### 2. `server/store/postgres/stores.go` Add to the `NewStores()` return: ```go Memories: NewMemoryStore(), ``` ### 3. `server/store/sqlite/stores.go` Add to the `NewStores()` return: ```go Memories: NewMemoryStore(), ``` ### 4. `server/main.go` Add after the existing tool registrations (~line 169): ```go // Memory tools (v0.18.0) — late registration, needs stores tools.RegisterMemoryTools(stores) ``` ### 5. `server/handlers/completion.go` In `loadConversation()`, add memory injection after the KB hint block (~line 798, after the `BuildKBHint` block): ```go // ── Memory injection (recall known facts about user) ── if memHint := BuildMemoryHint(context.Background(), h.stores, userID, personaID); memHint != \"\" { messages = append(messages, providers.Message{ Role: \"system\", Content: memHint, }) } ``` ### 6. `VERSION` ``` 0.18.0 ``` ### 7. `docs/ROADMAP.md` Mark Phase 1 items as complete (Data Model, Tools, Memory Injection basics). --- ## Testing Checklist 1. **Migration runs clean** — both Postgres and SQLite 2. **Tools register** — check startup logs for `🔧 Registered tool: memory_save` and `memory_recall` 3. **memory_save** — in a chat, tell the AI something personal (\"I prefer Go over Python\"). The AI should call memory_save. 4. **memory_recall** — in a NEW chat, ask \"what programming language do I prefer?\" The AI should call memory_recall and find it. 5. **Persona scoping** — with a Persona active, memories save as `persona_user` scope. Without a Persona, they save as `user` scope. 6. **Upsert** — saving the same key twice updates the value instead of creating a duplicate. 7. **Injection** — memories appear in the system prompt context (check server logs for `🧠 Injected N memories`). ## Architecture Notes - Memory injection happens in `loadConversation()` as a system message, same pattern as KB hints and compaction summaries - Scope priority in Recall: persona_user > persona > user (most specific wins) - The unique index on `(scope, owner_id, COALESCE(user_id, nil_uuid), key)` prevents duplicate keys within a scope - Confidence is LLM-provided: 1.0 for explicit statements, lower for inferences - Status field supports Phase 2's review pipeline (pending_review, archived) - Embedding column exists but is unused in Phase 1 — Phase 2 adds semantic recall