## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# First Query: The Full Cycle

This tutorial walks you through the core m1nd workflow: ingest, activate, learn, and observe the graph getting smarter. Then we explore structural holes and counterfactual simulation.

Prerequisites: You have completed the Quick Start and have m1nd running with a codebase ingested.

All examples use the JSON-RPC wire format. If you are working through an MCP client (Claude Code, Cursor, etc.), the client sends these calls for you when you invoke the tools by name.

## Step 1: Ingest Your Codebase

If you have not already ingested, do it now:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.ingest",
        "arguments": {
          "path": "/your/project",
          "agent_id": "dev"
        }
      }
    }

Response:

    {
      "files_processed": 335,
      "nodes_created": 9767,
      "edges_created": 26557,
      "languages": {"python": 335},
      "elapsed_ms": 910
    }

The graph now contains structural nodes (files, classes, functions) and edges (imports, calls, inheritance, co-change patterns). PageRank has been computed, giving each node a centrality score.

## Step 2: First Activation

Ask the graph about session pool management:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.activate",
        "arguments": {
          "query": "session pool management",
          "agent_id": "dev",
          "top_k": 5
        }
      }
    }

Response:

    {
      "activated": [
        {
          "node_id": "file::session_pool.py",
          "score": 0.89,
          "dimension_scores": {
            "structural": 0.92,
            "semantic": 0.95,
            "temporal": 0.78,
            "causal": 0.71
          }
        },
        {"node_id": "file::session_pool.py::class::SessionPool", "score": 0.84},
        {"node_id": "file::worker_pool.py", "score": 0.61},
        {"node_id": "file::session_pool.py::fn::acquire", "score": 0.58},
        {"node_id": "file::process_manager.py", "score": 0.45}
      ],
      "ghost_edges": [
        {
          "from": "file::session_pool.py",
          "to": "file::healing_manager.py",
          "confidence": 0.34
        }
      ]
    }

Reading the results:

- `score`: Combined 4-dimensional activation score (0.0 to 1.0)
- `dimension_scores`: Breakdown by structural (graph distance, PageRank), semantic (token overlap), temporal (co-change history), and causal (suspiciousness)
- `ghost_edges`: Connections the graph inferred but that are not explicit in code. Here, `session_pool.py` and `healing_manager.py` are structurally unconnected but co-activate together – a hidden dependency worth investigating.

Note the scores. We will come back to this query after teaching the graph.

## Step 3: Teach the Graph (Hebbian Learning)

The top two results (`session_pool.py` and the `SessionPool` class) were exactly what we needed. Tell the graph:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.learn",
        "arguments": {
          "query": "session pool management",
          "agent_id": "dev",
          "feedback": "correct",
          "node_ids": [
            "file::session_pool.py",
            "file::session_pool.py::class::SessionPool"
          ],
          "strength": 0.2
        }
      }
    }

Response:

    {
      "edges_strengthened": 740,
      "edges_weakened": 0,
      "plasticity_records": 740,
      "learning_type": "hebbian_ltp"
    }

What happened: Hebbian Long-Term Potentiation (LTP) strengthened 740 edges along paths connecting the confirmed-useful nodes. “Neurons that fire together wire together.” The next time anyone queries this region of the graph, those paths carry more signal.

Now suppose `worker_pool.py` (score 0.61) was not actually relevant. Mark it wrong:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.learn",
        "arguments": {
          "query": "session pool management",
          "agent_id": "dev",
          "feedback": "wrong",
          "node_ids": ["file::worker_pool.py"],
          "strength": 0.2
        }
      }
    }

Response:

    {
      "edges_strengthened": 0,
      "edges_weakened": 312,
      "plasticity_records": 1052,
      "learning_type": "hebbian_ltd"
    }

Long-Term Depression (LTD) weakened 312 edges leading to `worker_pool.py` from this query region. The graph now knows: for session pool queries, `worker_pool.py` is noise.

## Step 4: Activate Again – See the Improvement

Run the exact same query:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.activate",
        "arguments": {
          "query": "session pool management",
          "agent_id": "dev",
          "top_k": 5
        }
      }
    }

Expected changes:

    {
      "activated": [
        {"node_id": "file::session_pool.py", "score": 0.93},
        {"node_id": "file::session_pool.py::class::SessionPool", "score": 0.88},
        {"node_id": "file::session_pool.py::fn::acquire", "score": 0.65},
        {"node_id": "file::process_manager.py", "score": 0.47},
        {"node_id": "file::healing_manager.py", "score": 0.39}
      ]
    }

Compare with Step 2:

Node | Before | After | Change
--- | --- | --- | ---
`session_pool.py` | 0.89 | 0.93 | +0.04 (strengthened)
`SessionPool` class | 0.84 | 0.88 | +0.04 (strengthened)
`worker_pool.py` | 0.61 | dropped | Pushed below top-5 (weakened)
`healing_manager.py` | ghost only | 0.39 | Promoted from ghost to main results

The graph learned. `worker_pool.py` fell out of the top results. `healing_manager.py`, previously only a ghost edge, got promoted because the strengthened paths through `session_pool.py` now carry more signal to its neighborhood.

This is the core value proposition of m1nd: every interaction makes the graph smarter. No other code intelligence tool does this.

## Step 5: Structural Hole Detection

Ask the graph what is missing around a topic:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.missing",
        "arguments": {
          "query": "database connection pooling",
          "agent_id": "dev"
        }
      }
    }

Response:

    {
      "holes": [
        {
          "region": "connection lifecycle",
          "adjacent_nodes": 4,
          "description": "No dedicated connection pool abstraction"
        },
        {
          "region": "pool metrics",
          "adjacent_nodes": 3,
          "description": "No pool health monitoring"
        },
        {
          "region": "graceful drain",
          "adjacent_nodes": 2,
          "description": "No connection drain on shutdown"
        }
      ],
      "total_holes": 9
    }

What happened: m1nd activated the “database connection pooling” region of the graph and looked for gaps – areas where the graph’s structure predicts a node should exist but none does. These are structural holes: places where other codebases of similar shape would have components but yours does not.

This is not a linter or rule-based checker. It is topology-based gap detection. The graph’s shape implies these components should exist, based on the relationships between the nodes that do exist.

## Step 6: Counterfactual Simulation

Before deleting or rewriting a module, simulate the consequences:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.counterfactual",
        "arguments": {
          "node_ids": ["file::spawner.py"],
          "agent_id": "dev"
        }
      }
    }

Response:

    {
      "cascade": [
        {"depth": 1, "affected": 23},
        {"depth": 2, "affected": 456},
        {"depth": 3, "affected": 3710}
      ],
      "total_affected": 4189,
      "orphaned_count": 0,
      "pct_activation_lost": 0.41
    }

Reading the results:

- Depth 1: 23 nodes directly depend on `spawner.py`
- Depth 2: 456 more nodes depend on those 23
- Depth 3: 3,710 more – a cascade explosion
- Total: 4,189 nodes affected out of ~9,767 (42.9% of the graph)
- Activation lost: 41% of the graph’s total activation capacity would be disrupted

Compare this with removing `config.py`:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.counterfactual",
        "arguments": {
          "node_ids": ["file::config.py"],
          "agent_id": "dev"
        }
      }
    }

Response:

    {
      "cascade": [
        {"depth": 1, "affected": 89},
        {"depth": 2, "affected": 1234},
        {"depth": 3, "affected": 1208}
      ],
      "total_affected": 2531,
      "orphaned_count": 3,
      "pct_activation_lost": 0.28
    }

Despite `config.py` having more direct dependents (89 vs 23), its total cascade is smaller (2,531 vs 4,189). `spawner.py` sits at a structural chokepoint where downstream nodes have more transitive dependencies. This insight is impossible to get from `grep` or import analysis alone – it requires full graph traversal.

## Step 7: Hypothesis Testing (Bonus)

Test a structural claim against the graph:

    {
      "method": "tools/call",
      "params": {
        "name": "m1nd.hypothesize",
        "arguments": {
          "claim": "worker_pool depends on whatsapp_manager at runtime",
          "agent_id": "dev"
        }
      }
    }

Response:

    {
      "verdict": "likely_true",
      "confidence": 0.72,
      "paths_explored": 25015,
      "evidence": [
        {
          "path": [
            "file::worker_pool.py",
            "file::process_manager.py::fn::cancel",
            "file::whatsapp_manager.py"
          ],
          "hops": 2
        }
      ],
      "note": "2-hop dependency via cancel function -- invisible to grep"
    }

The hypothesis engine explored 25,015 paths in 58ms and found a 2-hop dependency that no text search could reveal: the worker pool reaches the WhatsApp manager through a cancel function in the process manager. This is the kind of hidden coupling that causes production incidents.

## Summary: The Learning Loop

The core m1nd workflow is a feedback loop:

    ingest  -->  activate  -->  use results  -->  learn  -->  activate again
      |                                              |
      |              (graph gets smarter)            |
      +----------------------------------------------+

Every `learn` call shifts edge weights. Every subsequent `activate` benefits from accumulated learning. Over sessions, the graph adapts to how your team thinks about your codebase.

Additional tools layer on top of this foundation:

Tool | When to Use
--- | ---
`missing` | Before designing new features – find what your codebase lacks
`counterfactual` | Before deleting or rewriting – simulate the blast radius
`hypothesize` | When debugging – test assumptions about hidden dependencies
`impact` | Before modifying a file – understand the blast radius
`predict` | After modifying a file – which other files probably need changes too
`trace` | When an error occurs – map stacktraces to structural root causes

Next: Multi-Agent Tutorial – how multiple agents share one graph.