Skip to content

feat(memory): graph memory schema, core types, and CRUD operations #1224

@bug-ops

Description

@bug-ops

Summary

Phase 1 of graph memory (#1222): SQLite schema, Rust types, CRUD store, config section.

Depends on: #1223 (prerequisite refactors)

Tasks

1. Migration 021_knowledge_graph.sql

Create crates/zeph-memory/migrations/021_knowledge_graph.sql:

  • graph_entities (id, name, entity_type, summary, first_seen_at, last_seen_at, qdrant_point_id) with UNIQUE(name, entity_type)
  • graph_edges (id, source_entity_id, target_entity_id, relation, fact, confidence, valid_from, valid_to, created_at, expired_at, episode_id, qdrant_point_id) with CASCADE/SET NULL FKs
  • graph_communities (id, name, summary, entity_ids JSON, timestamps)
  • graph_metadata (key, value) for persistent counters
  • ALTER TABLE messages ADD COLUMN graph_processed INTEGER NOT NULL DEFAULT 0
  • Indexes: edges source/target, edges valid_to partial, entities name COLLATE NOCASE, entities type, entities last_seen_at

Tables are always created (not feature-gated) to avoid migration ordering issues.

2. Rust Types (graph/types.rs)

  • EntityType enum (Person, Tool, Concept, Project, Language, File, Config, Organization) with FromStr/Display/serde
  • Entity, Edge, Community structs matching SQLite schema
  • GraphFact with decomposed scoring (entity_match_score, hop_distance, confidence) and composite_score() method

3. CRUD Store (graph/store.rs)

GraphStore with methods:

  • upsert_entity, find_entity, find_entities_fuzzy, all_entities_stream, all_entities, entity_count
  • insert_edge, invalidate_edge, edges_for_entity, edges_between, active_edge_count
  • upsert_community, community_for_entity, all_communities, community_count
  • bfs(start_entity_id, max_hops) using recursive CTE (3 queries total)

4. Feature Flag

  • Root Cargo.toml: graph-memory = ["zeph-memory/graph-memory", "zeph-core/graph-memory"]
  • zeph-memory/Cargo.toml: graph-memory = []
  • zeph-core/Cargo.toml: graph-memory = ["zeph-memory/graph-memory"]
  • lib.rs: #[cfg(feature = "graph-memory")] pub mod graph;

5. Config (GraphConfig)

Add GraphConfig to crates/zeph-core/src/config/types.rs with fields: enabled, extract_model, max_entities_per_message, max_edges_per_message, community_refresh_interval, entity_similarity_threshold, extraction_timeout_secs, use_embedding_resolution, max_hops, recall_limit. Add graph: GraphConfig field on MemoryConfig.

6. Error Variant

Add GraphStore(String) variant to MemoryError.

Architecture Reference

See .local/plan/graph-memory-architecture.md Section 3 for exact SQL, type signatures, and BFS CTE query.

Acceptance Criteria

  • Migration 021 applies cleanly on existing and new databases
  • GraphStore::upsert_entity handles insert and update (UNIQUE constraint)
  • GraphStore::insert_edge creates edges with correct FKs
  • GraphStore::invalidate_edge sets expired_at and valid_to
  • GraphStore::bfs with max_hops=0 returns only start entity
  • GraphStore::bfs with max_hops=2 traverses correctly on test graph
  • GraphConfig deserializes from TOML with defaults
  • EntityType::from_str handles all variants + rejects unknown
  • Config snapshot test updated
  • ~22 tests (20 unit + 2 integration)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgraph-memoryKnowledge graph memory featurememoryzeph-memory crate (SQLite)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions