memories.sh logomemories.sh
SDK

Memory Graph Architecture

How graph nodes and edges are extracted, stored, retrieved, and guarded in memories.sh.

This page describes the graph pipeline end-to-end: write path, storage model, hybrid retrieval, and rollout guardrails.

Why The Graph Exists

Baseline retrieval ranks memories by text relevance. The graph layer adds relationship traversal so related memories can be recalled even when exact query terms differ.

Examples:

  • Query mentions rollout alarms, but the best supporting memory is connected through topic:dashboard.
  • Query mentions hybrid strategy, and related decision or rule memories are reached through graph edges instead of keyword overlap.

Storage Model

Graph storage is maintained in the workspace Turso database:

  • graph_nodes: canonical entities (memory, repo, topic, category, memory_type, etc.)
  • graph_edges: typed, weighted directional relationships between nodes
  • memory_node_links: mapping between each memory and its extracted nodes

Every memory is also represented as a first-class memory node (node_key = memory_id) and linked back with role self. This enables direct memory-to-memory edges in later graph phases without schema changes.

Primary code paths:

  • /Users/tradecraft/dev/memories/packages/web/src/lib/memory-service/graph/upsert.ts
  • /Users/tradecraft/dev/memories/packages/web/src/lib/memory-service/graph/retrieval.ts
  • /Users/tradecraft/dev/memories/packages/web/src/lib/memory-service/graph/status.ts

Write Path

  1. A memory write/update enters memory mutation handlers.
  2. Graph extraction produces node and edge candidates from memory content and metadata, including the memory's own memory node.
  3. upsert.ts ensures schema, upserts nodes, writes memory-node links (self, type, tag, etc.), writes evidence-backed edges, and prunes stale links for edited/forgotten memories.
  4. When embeddings are available, similarity sync writes bidirectional similar_to edges between memory nodes for high-cosine neighbors. If LLM extraction is enabled, ambiguous-neighbor pairs are additionally classified into contradicts or supersedes.
  5. Cleanup removes orphan graph nodes with no links or edges.

Behavior is best-effort: memory writes stay available even if graph indexing fails.

Read Path (Hybrid Retrieval)

Hybrid retrieval runs in layered recall logic:

  1. Baseline candidates are gathered from rules, working memories, and long-term memories.
  2. If request strategy is hybrid_graph and rollout allows it, graph expansion traverses related nodes/edges from seed memories.
  3. Graph-expanded memories are appended with provenance metadata (whyIncluded: graph_expansion, linked node, edge type, hop count).
  4. If graph expansion errors or rollout disallows application, retrieval falls back safely to baseline.

Graph expansion can include semantically related memories via similar_to edges, even without shared tags/categories.

Graph candidate ranking is edge-type aware and confidence-weighted. For equal hop counts, higher-priority relationships (for example caused_by, contradicts, supersedes) outrank generic relational links.

Edge Weight Table

The retrieval ranker applies edge-type multipliers before hop decay:

Edge typeWeightWhy
caused_by1.5Causal updates should dominate older generic preference facts
contradicts1.3Surface conflicts quickly for clarification
supersedes1.2Prefer newer refinement over stale variants
similar_to1.0Semantic neighbor baseline
depends_on0.9Preserve workflow ordering context
prefers_over0.8Preference edges with lower certainty than causal updates
specializes0.7Hierarchical narrowing
conditional_on0.6Condition-gated relationships
shared_node0.25Legacy/shared metadata traversal fallback

Ranking formula:

score = (edge_type_weight * edge_weight * confidence) / max(1, hop_count)

At equal confidence and hop count, caused_by will outrank prefers_over, which is how causal facts can override older stated preferences.

Fallback reasons include:

  • feature_flag_disabled
  • rollout_off
  • shadow_mode
  • quality_gate_blocked
  • graph_expansion_error
  • rollout_guardrail

Rollout And Safety Controls

Workspace rollout mode controls whether hybrid expansion is applied:

  • off: baseline only
  • shadow: execute graph path for metrics, return baseline
  • canary: apply graph expansion for strategy: hybrid_graph requests

Safety and observability are emitted through graph status and trace payloads:

  • /api/sdk/v1/graph/status
  • /api/sdk/v1/graph/rollout
  • /api/sdk/v1/graph/trace

Canary mode is also protected by a quality gate that evaluates fallback and relevance regressions over rolling windows before allowing canary application.

Similarity Edge Configuration

Similarity edge extraction is controlled by environment variables:

  • SIMILARITY_EDGE_THRESHOLD (default 0.85): cosine score cutoff for similar_to edge creation.
  • SIMILARITY_EDGE_MAX_K (default 20): max candidate embeddings scanned per write.
  • SIMILARITY_EDGE_MAX_PER_MEMORY (default 5): max neighbors retained per memory after ranking.

LLM Relationship Extraction Configuration

When GRAPH_LLM_EXTRACTION_ENABLED=true, ambiguous similarity matches can be classified into additional relationship edges:

  • contradicts: bidirectional conflict relationship.
  • supersedes: directional "newer memory refines older memory" relationship.
  • semantic extraction edges: caused_by, prefers_over, depends_on, specializes, conditional_on.

conditional_on edges link memories to shared condition nodes (for example time:morning), which are auto-created and reused during graph upsert.

Environment controls:

  • GRAPH_LLM_AMBIGUOUS_SIMILARITY_MIN (default 0.70)
  • GRAPH_LLM_AMBIGUOUS_SIMILARITY_MAX (default 0.90)
  • GRAPH_LLM_RELATIONSHIP_CONFIDENCE_THRESHOLD (default 0.70)
  • GRAPH_LLM_RELATIONSHIP_MODEL_ID (default anthropic/claude-3-5-haiku-latest)
  • GRAPH_LLM_SEMANTIC_CONTEXT_LIMIT (default 20)
  • GRAPH_LLM_SEMANTIC_CONFIDENCE_THRESHOLD (default 0.60)
  • GRAPH_LLM_SEMANTIC_MIN_CHARS (default 20)

Contradiction Detection Pipeline

Contradiction/refinement extraction runs in the async embedding worker:

  1. Compute similarity neighbors from memory_embeddings.
  2. Filter to ambiguous matches using GRAPH_LLM_AMBIGUOUS_SIMILARITY_MIN..MAX.
  3. Classify each pair as agrees, contradicts, refines, or unrelated.
  4. Persist only edges meeting GRAPH_LLM_RELATIONSHIP_CONFIDENCE_THRESHOLD.

Outputs:

  • contradicts (bidirectional memory-memory edge)
  • supersedes (directional memory-memory edge)

Semantic Relationship Extraction Pipeline

Semantic extraction also runs asynchronously in the embedding worker and does not block memory writes:

  1. Select recent scoped memories (GRAPH_LLM_SEMANTIC_CONTEXT_LIMIT).
  2. Send new-memory + recent-memory context to the configured model with strict JSON schema output.
  3. Parse + validate typed edges (caused_by, prefers_over, depends_on, specializes, conditional_on).
  4. Drop low-confidence edges (< GRAPH_LLM_SEMANTIC_CONFIDENCE_THRESHOLD).
  5. Persist edges with evidence metadata; map conditional_on to shared condition nodes.

Cost And Operations Note

Enabling GRAPH_LLM_EXTRACTION_ENABLED adds model calls per memory write (pairwise ambiguous classification + semantic extraction pass). These calls run in background embedding jobs and are best-effort.

Operationally:

  • memory writes still succeed if extraction fails
  • extraction failures are logged as best-effort degradation and surfaced in embedding job metrics as GRAPH_RELATIONSHIP_PARTIAL_DEGRADE
  • issue-level extraction codes are recorded (GRAPH_LLM_CLASSIFICATION_FAILED, GRAPH_LLM_SEMANTIC_EXTRACTION_FAILED) to make rollout regressions visible
  • retries after GRAPH_RELATIONSHIP_SYNC_FAILED reuse stored embeddings when available to avoid repeated embedding API calls for graph-only failures
  • monitor AI Gateway usage when enabling this in high-write tenants
  • embedding usage endpoints currently report embedding spend, not a separate semantic-extraction meter

Scope And Workspace Routing

Graph data respects the same routing model as memories:

  • tenantId: AI SDK Project selector (security/database boundary)
  • userId: end-user scope inside tenantId
  • projectId: optional project/repo context filter (not an auth boundary)

When workspace repo-routing mode is auto, org repos route to org workspace memory and personal repos route to personal workspace memory by default.

You can also set explicit owner mappings in Settings → Repo Workspace Routing to handle org-owned repos that do not match your workspace slug.

Examples:

  • projectId: "github.com/jane/side-project" with no mapping routes to personal memory.
  • projectId: "github.com/webrenew/memories" routes to the webrenew org workspace when you are a member.
  • Mapping acme-platform -> org_acme routes projectId: "github.com/acme-platform/backend" to the selected org_acme workspace even if the slug differs.

Dashboard Explorer Mapping

The dashboard graph explorer (Memory Graph section) reads from /api/graph/explore and renders:

  • Relationship graph (interactive node/edge view)
  • Selected edge metadata (direction, weight, confidence, evidence, expiry)
  • Linked memories and evidence highlighting

This view is designed for debugging retrieval quality and data linkage, not only for health checks.

On this page