Skip to main content
Watercooler’s memory graph system transforms threads into a queryable knowledge graph with embeddings, summaries, and cross-references.

Architecture Overview

Graph-First Design

All thread operations follow a graph-first approach:
  1. Write to Graph: Data written to nodes.jsonl and edges.jsonl first
  2. Project to Markdown: The .md file is generated from the graph
  3. Enrich: Summaries and embeddings added asynchronously
  4. Query: Search across threads using keywords, semantics, or filters
Thread Operation (say/ack/handoff)
    |
    v
[Graph Writer] ────> nodes.jsonl, edges.jsonl
    |                       |
    v                       v
[Projector] ──────> thread.md
    |
    v
[Enrichment] ────> Add summaries & embeddings
    |
    v
[Search] ─────────> Query graph

Storage Format

Threads are stored in per-thread JSONL format:
threads/
└── graph/
    └── baseline/
        ├── manifest.json           # Graph metadata
        ├── search-index.jsonl      # Cross-thread embeddings
        └── threads/
            └── <topic>/
                ├── meta.json       # Thread node
                ├── entries.jsonl   # Entry nodes (one per line)
                └── edges.jsonl     # Relationships

Building Memory Graphs

1
Step 1: Create threads with content
2
watercooler init-thread api-design
watercooler say api-design \
  --title "REST vs GraphQL analysis" \
  --body "Evaluated both approaches. GraphQL provides better flexibility for mobile clients."

watercooler say api-design \
  --title "Decision: GraphQL" \
  --type Decision \
  --body "Moving forward with GraphQL. Will use Apollo Server with TypeScript."
3
Step 2: Build the graph
4
The graph is built automatically when you use graph-canonical commands (say, ack, handoff). To manually build/rebuild:
5
watercooler baseline-graph build --threads-dir ./threads
6
This:
7
  • Parses all thread markdown files
  • Generates LLM summaries for entries and threads
  • Creates embeddings for semantic search
  • Exports to JSONL graph format
  • Builds search index
  • 8
    Step 3: Verify the graph
    9
    Check graph statistics:
    10
    watercooler baseline-graph stats --threads-dir ./threads
    
    11
    Output:
    12
    Threads: 12
    Entries: 147
    Nodes: 159
    Edges: 158
    Embeddings: 147
    Storage: 2.3 MB
    

    Graph Pipeline Options

    Configuration

    The pipeline supports various modes:
    watercooler baseline-graph build \
      --threads-dir ./threads
    
    • Uses local LLM for summaries (llama-server)
    • Generates embeddings
    • Processes all threads

    Test Mode

    Process only a subset of threads:
    watercooler baseline-graph build \
      --threads-dir ./threads \
      --test-limit 5
    

    Fresh Build

    Clear cache and rebuild everything:
    watercooler baseline-graph build \
      --threads-dir ./threads \
      --fresh
    

    Querying the Graph

    Search entry bodies, titles, and summaries:
    watercooler baseline-graph search \
      --query "authentication" \
      --threads-dir ./threads
    
    Output:
    {
      "results": [
        {
          "node_type": "entry",
          "node_id": "01H2K3M4N5P6Q7R8S9T0",
          "score": 1.8,
          "matched_fields": ["title", "body"],
          "entry": {
            "entry_id": "01H2K3M4N5P6Q7R8S9T0",
            "thread_topic": "auth-redesign",
            "title": "JWT authentication flow",
            "body": "Implemented JWT-based authentication...",
            "agent": "Bob",
            "role": "implementer"
          }
        }
      ],
      "total": 1
    }
    
    Find conceptually similar content using embeddings:
    watercooler baseline-graph search \
      --query "how do we handle user sessions?" \
      --semantic \
      --threads-dir ./threads
    
    Semantic search:
    • Uses cosine similarity on embeddings
    • Finds conceptually related content
    • Works even with different wording
    • Requires embeddings (run build without --skip-embeddings)

    Filters

    Combine search with filters:
    # Find decisions made by Alice
    watercooler baseline-graph search \
      --query "database" \
      --entry-type Decision \
      --agent Alice \
      --threads-dir ./threads
    
    # Find recent planner entries
    watercooler baseline-graph search \
      --role planner \
      --start-time "2026-03-01T00:00:00Z" \
      --threads-dir ./threads
    
    # Find entries in specific thread
    watercooler baseline-graph search \
      --query "implementation" \
      --thread-topic api-design \
      --threads-dir ./threads
    
    Available Filters:
    • --thread-topic: Filter by specific thread
    • --thread-status: OPEN, CLOSED, BLOCKED, ABANDONED
    • --role: planner, implementer, critic, tester, pm, scribe
    • --entry-type: Note, Plan, Decision, PR, Closure
    • --agent: Filter by agent name
    • --start-time: ISO timestamp (entries after)
    • --end-time: ISO timestamp (entries before)
    • --limit: Max results (default: 10)

    Similar Entries

    Find entries similar to a specific entry:
    watercooler baseline-graph search \
      --similar-to "01H2K3M4N5P6Q7R8S9T0" \
      --threads-dir ./threads
    
    Uses embeddings to find conceptually similar entries across all threads.

    Graph Structure

    Node Types

    Thread Node (meta.json)

    {
      "id": "thread:api-design",
      "type": "thread",
      "topic": "api-design",
      "title": "API Design Discussion",
      "status": "CLOSED",
      "ball": "team",
      "created": "2026-03-01T10:00:00Z",
      "last_updated": "2026-03-06T15:30:00Z",
      "entry_count": 12,
      "summary": "Evaluated REST vs GraphQL, decided on GraphQL with Apollo Server."
    }
    

    Entry Node (entries.jsonl)

    {
      "id": "entry:01H2K3M4N5P6Q7R8S9T0",
      "type": "entry",
      "entry_id": "01H2K3M4N5P6Q7R8S9T0",
      "thread_topic": "api-design",
      "index": 0,
      "agent": "Alice",
      "role": "planner",
      "entry_type": "Plan",
      "title": "REST vs GraphQL analysis",
      "body": "Evaluated both approaches...",
      "timestamp": "2026-03-01T10:05:00Z",
      "summary": "Compared REST and GraphQL for API design. GraphQL offers better flexibility.",
      "embedding": [0.023, -0.145, 0.891, ...],
      "code_branch": "feature/api-design"
    }
    

    Edge Types

    Contains Edge

    {
      "type": "contains",
      "source": "thread:api-design",
      "target": "entry:01H2K3M4N5P6Q7R8S9T0",
      "timestamp": "2026-03-01T10:05:00Z"
    }
    

    Followed By Edge

    {
      "type": "followed_by",
      "source": "entry:01H2K3M4N5P6Q7R8S9T0",
      "target": "entry:01H2K3M4N5P6Q7R8S9T1",
      "timestamp": "2026-03-01T11:20:00Z"
    }
    

    References Edge (Cross-Thread)

    {
      "type": "references",
      "source": "entry:01H2K3M4N5P6Q7R8S9T5",
      "target": "entry:01H2K3M4N5P6Q7R8S9T0",
      "mention": "As decided in api-design thread"
    }
    

    Enrichment

    Summaries

    LLM-generated summaries provide:
    • Concise entry overviews (1-2 sentences)
    • Thread-level summaries (key decisions and outcomes)
    • Extractive fallback (no LLM required)
    Entry Summary Example:
    Original: "After analyzing both REST and GraphQL, I found that GraphQL 
    provides better flexibility for our mobile clients. The ability to 
    request exactly the fields needed reduces payload size by ~60%..."
    
    Summary: "Compared REST and GraphQL; GraphQL offers better flexibility 
    and 60% smaller payloads for mobile clients."
    

    Embeddings

    Vector embeddings enable:
    • Semantic search
    • Similar entry discovery
    • Conceptual clustering
    • Cross-thread relationship detection
    Model: Uses OpenAI-compatible embedding endpoint (default: text-embedding-3-small) Dimension: 1536 (default)

    Configuration

    Configure LLM and embedding services via environment variables:
    # LLM for summaries (local llama-server)
    export WATERCOOLER_LLM_API_BASE="http://localhost:8080/v1"
    export WATERCOOLER_LLM_MODEL="llama-3.1-8b"
    
    # Embedding service
    export WATERCOOLER_EMBEDDING_API_BASE="http://localhost:8081/v1"
    export WATERCOOLER_EMBEDDING_MODEL="text-embedding-3-small"
    
    Or use config file (~/.watercooler/config.toml):
    [llm]
    api_base = "http://localhost:8080/v1"
    model = "llama-3.1-8b"
    timeout = 30
    
    [embedding]
    api_base = "http://localhost:8081/v1"
    model = "text-embedding-3-small"
    

    Graph Operations

    List Threads

    watercooler baseline-graph list-threads \
      --threads-dir ./threads \
      --status OPEN
    

    List Entries

    watercooler baseline-graph list-entries api-design \
      --threads-dir ./threads
    

    Read Entry

    watercooler baseline-graph read-entry \
      --entry-id "01H2K3M4N5P6Q7R8S9T0" \
      --threads-dir ./threads
    

    Export Thread

    Project a thread back to markdown from graph:
    watercooler baseline-graph project \
      --topic api-design \
      --threads-dir ./threads
    

    Reconcile Graph

    Fix inconsistencies between markdown and graph:
    watercooler baseline-graph reconcile \
      --threads-dir ./threads
    

    Performance

    Incremental Builds

    Incremental mode dramatically speeds up subsequent builds:
    # First build: 10 threads, 150 entries
    watercooler baseline-graph build --threads-dir ./threads
    # → ~5 minutes (summaries + embeddings)
    
    # Second build: 2 changed threads, 8 new entries
    watercooler baseline-graph build \
      --threads-dir ./threads \
      --incremental
    # → ~30 seconds (only changed content)
    
    Incremental builds:
    • Track thread modification times
    • Cache summaries and embeddings
    • Only reprocess changed threads
    • Store state in graph/baseline/state.json

    Parallelization

    The pipeline uses parallel workers for LLM calls:
    # Default: 4 workers
    watercooler baseline-graph build --threads-dir ./threads
    
    # More workers (faster but more memory)
    export WATERCOOLER_LLM_WORKERS=8
    watercooler baseline-graph build --threads-dir ./threads
    

    Optimization Tips

    1. Use incremental mode for frequent builds
    2. Skip embeddings if you don’t need semantic search
    3. Use extractive summaries for faster builds during development
    4. Increase workers if you have available CPU/memory
    5. Use test-limit for development/testing

    Integration with FalkorDB

    For advanced graph queries, export to FalkorDB:
    # Export to FalkorDB format
    watercooler baseline-graph export-falkordb \
      --threads-dir ./threads \
      --output ./falkordb-data
    
    # Import to FalkorDB instance
    falkordb-cli GRAPH.QUERY watercooler "@./falkordb-data/import.cypher"
    
    FalkorDB enables:
    • Cypher graph queries
    • Path traversal
    • Complex relationship queries
    • Graph visualizations

    Best Practices

    1. Build Graphs Regularly

    Run incremental builds after batch updates:
    # After creating multiple threads
    watercooler baseline-graph build \
      --threads-dir ./threads \
      --incremental
    

    2. Use Semantic Search for Exploration

    Keyword search for precise matches, semantic for discovery:
    # Find exact mentions
    watercooler baseline-graph search --query "Redis cache"
    
    # Find related concepts
    watercooler baseline-graph search \
      --query "caching strategies" \
      --semantic
    

    3. Archive Closed Threads

    Exclude closed threads from active builds:
    watercooler baseline-graph build \
      --threads-dir ./threads \
      --skip-closed
    

    4. Monitor Graph Health

    Check for issues:
    watercooler baseline-graph check-health \
      --threads-dir ./threads
    
    Mention related threads in entries:
    watercooler say new-feature \
      --title "Building on auth-redesign" \
      --body "Using the JWT approach from auth-redesign thread. Adding refresh tokens."
    
    The graph will automatically create reference edges.

    Troubleshooting

    Graph Not Available

    If commands fail with “graph not yet built”:
    watercooler baseline-graph build --threads-dir ./threads
    

    Stale Graph

    If graph is out of sync with markdown:
    watercooler baseline-graph reconcile \
      --threads-dir ./threads
    

    Missing Embeddings

    If semantic search returns no results:
    # Check if embeddings exist
    watercooler baseline-graph stats --threads-dir ./threads
    
    # Rebuild with embeddings
    watercooler baseline-graph build \
      --threads-dir ./threads \
      --fresh
    

    LLM Connection Issues

    Verify LLM server is running:
    curl http://localhost:8080/v1/models
    
    Or use extractive mode:
    watercooler baseline-graph build \
      --threads-dir ./threads \
      --extractive-only
    

    Next Steps

    Multi-Agent Workflows

    Design collaborative workflows that populate memory graphs

    Branch Pairing

    Sync graphs with Git branches

    Build docs developers (and LLMs) love