Knowledge Graph & Memory
How Memory Works
Working Mind uses a native SQLite knowledge graph stored at ~/.wmind/memory.sqlite. Entities, relations, and observations are stored as structured rows with foreign keys, indexes, and FTS5 full-text search. No external MCP server is needed -- memory is built into the agent.
The knowledge graph is shared across all sessions. Every session can read and write to the graph. When you start a new session, the agent already knows everything from previous sessions.
Entities
An entity is a node in the knowledge graph. It has a name, a type, and one or more observations.
Entity: "Project Alpha"
Type: project
Observations:
- "Uses React 19 with Server Components"
- "Deployed on Vercel"
- "Team lead is Sarah Chen"
Entity Types
Common types the agent uses:
| Type | Example |
|---|---|
| person | Sarah Chen |
| organization | Acme Corp |
| concept | Quantum Error Correction |
| technology | React 19 |
| project | Project Alpha |
| event | Q4 Planning Meeting |
| auto | Auto-created when referenced by a relation or observation |
| system | Internal entities like __source__ |
Types are not fixed. The agent can create any type it determines is appropriate.
Relations
Relations connect entities to each other.
"Project Alpha" --uses--> "React 19"
"Sarah Chen" --leads--> "Project Alpha"
"Project Alpha" --deployed_on--> "Vercel"
Relations are directional. The agent creates them automatically when you mention connections. If a relation references an entity that does not yet exist, the entity is auto-created with type auto.
How Knowledge Gets Saved
Explicit Instructions
You: "Remember that Project Alpha uses React 19 with Server Components"
Agent: Created entity "Project Alpha" (project)
Added observation: "Uses React 19 with Server Components"
Document Ingestion
/ingest research-notes.md
The agent reads the file, extracts entities, searches the graph for duplicates, and creates or updates entities and relations.
Agent-Initiated
The agent may save important findings autonomously, especially when the starter pack's "wiki behavior" is active. It saves syntheses, comparisons, and analyses as entities.
Contradiction Detection
When you add an observation that contradicts an existing one, Working Mind detects the conflict automatically. It invalidates the old observation and preserves the timeline.
For example, if the graph stores "prefers Python" and you later say "prefers Rust", the old observation is marked as invalidated with a timestamp, and the new one is added. Both are preserved -- you can query the graph as it was last month, or as it is now.
Current detection patterns:
| Pattern Group | Examples |
|---|---|
| preference | "prefers X", "favorite X" |
| state | "status: X", "role: X", "title: X" |
| scalar | "population: X", "temperature: X", "age: X" |
| location | "lives in X", "based in X", "works at X" |
Temporal Validity
Every observation and relation has valid_at and invalidated_at timestamps. This means:
- You can query the graph as it existed at any point in time
- Contradictions are resolved by invalidation, not deletion
- The full history is preserved for auditing and review
Knowledge Index
The system prompt includes a truncated index of all entities in the knowledge graph. This lets the agent know what exists before deciding whether to create new entities or update existing ones.
The index is refreshed automatically after writes to the graph.
Cross-Linking
When you add observations that mention existing entity names, the agent automatically creates relations between them. This is how the graph becomes interconnected over time.
Memory Tools
The agent uses native tools to interact with the graph:
| Tool | Description |
|---|---|
memory_create_entities | Create new entities |
memory_add_observations | Add observations to entities (auto-creates entity if missing) |
memory_create_relations | Create relations between entities (auto-creates entities if missing) |
memory_delete_entities | Delete entities and their observations |
memory_delete_observations | Delete specific observations |
memory_delete_relations | Delete specific relations |
memory_read_graph | Read the entire graph |
memory_search_nodes | Search the graph by query (FTS5) |
memory_open_nodes | Open specific nodes by name |
memory_search_facts | Search facts with graph traversal |
memory_invalidate_obs | Invalidate an observation with timestamp |
memory_search_history | Time-travel search -- query the graph as it was at a past date |
Storage Details
- Format: SQLite database with WAL mode and foreign keys
- Location:
~/.wmind/memory.sqlite - Legacy: If
~/.wmind/memory.jsonlexists from a previous version, it is automatically migrated to SQLite on first run. The original file is renamed to.migrated.<timestamp>. - Corruption recovery: On every open,
PRAGMA integrity_checkruns. If the database is corrupt, it is renamed to.corrupt.<timestamp>and a fresh database is created. - FTS5: Full-text search on observations for fast
search_nodesqueries. Falls back to LIKE queries if FTS5 is not available.
/memory Command
The TUI provides a /memory command for direct graph management:
| Subcommand | Description |
|---|---|
/memory status | Show entity and observation counts |
/memory save | Save the current conversation context to the graph |
/memory use <name> | Switch to a named memory store |
/memory list | List all memory stores |
/memory rename <old> <new> | Rename a store |
/memory delete <name> | Delete a store |
Current Limitations
- Exact name matching -- cross-linking requires exact entity name matches; "React" and "React 19" are different entities
- Pattern-based contradiction detection -- only detects contradictions for known patterns (preference, state, scalar, location); does not use LLM reasoning for conflict detection
- Truncated index -- knowledge index in system prompt is capped, large graphs get truncated
- Single user -- no multi-tenancy, no concurrent writes