How /understand-diff Performs Impact Analysis for Code Changes

The /understand-diff endpoint analyzes Git diffs by mapping changed files to knowledge graph nodes, propagating one-hop relationships to identify affected components, and generating a risk-aware markdown report based on complexity metrics and architectural cross-dependencies.

The Understand-Anything repository provides a semantic code analysis system that transforms raw Git diffs into structured impact assessments. By traversing a persisted knowledge graph stored in .understand-anything/knowledge-graph.json, the system reveals hidden dependencies and architectural risks that traditional diff tools cannot detect.

Three-Phase Impact Analysis Architecture

The impact analysis operates through three tightly coupled phases implemented in understand-anything-plugin/src/diff-analyzer.ts. Each phase progressively expands the scope of detected changes to surface ripple effects across the codebase.

Phase 1: Mapping Changed Files to Graph Nodes

The algorithm begins by correlating files from git diff … --name-only with GraphNode entities in the knowledge graph. In buildDiffContext (lines 31–41), the system iterates over changedFiles and compares each path against the filePath field of every node. Matching node IDs are recorded as changed nodes, while files without corresponding graph entries are flagged as unmapped for manual review.

Phase 2: Propagating One-Hop Relationships

Next, the system executes edge traversal (lines 57–69) to capture immediate dependencies. The algorithm scans all GraphEdge records, marking any edge where the source or target matches a changed node as impacted. The opposite endpoint of each impacted edge is added to the affected nodes set, unless it is already a changed node. This implementation also handles contains relationships specifically, ensuring that child entities of changed files are included in the changed set before propagation begins.

Phase 3: Deriving Higher-Level Impact and Risk Assessment

Finally, the system aggregates impacted node IDs to determine affected layers (lines 74–77). The formatDiffAnalysis function (starting at line 90) generates a markdown report containing changed components, affected components, impacted edges, and affected architectural layers. The risk assessment logic (lines 58–94) evaluates four critical factors:

  • Node complexity: Flags changes to nodes marked complex versus simple
  • Cross-layer impact: Detects when changes span multiple architectural layers
  • Blast radius: Alerts when downstream affected nodes exceed five components
  • Unmapped files: Notes files present in the diff but absent from the knowledge graph

Core Algorithm Implementation

The following TypeScript excerpt from src/diff-analyzer.ts demonstrates the exact logic used to build the diff context:

// 1️⃣ Identify changed nodes
for (const file of changedFiles) {
  let mapped = false;
  for (const node of nodes) {
    if (node.filePath === file) {
      changedNodeIds.add(node.id);
      mapped = true;
    }
  }
  if (!mapped) unmappedFiles.push(file);
}

// 2️⃣ Include "contains" children of changed file nodes
for (const edge of edges) {
  if (edge.type === "contains" && changedNodeIds.has(edge.source)) {
    changedNodeIds.add(edge.target);
  }
}

// 3️⃣ 1-hop propagation → affected nodes & impacted edges
for (const edge of edges) {
  const sourceChanged = changedNodeIds.has(edge.source);
  const targetChanged = changedNodeIds.has(edge.target);
  if (sourceChanged || targetChanged) {
    impactedEdges.push(edge);
    if (sourceChanged && !changedNodeIds.has(edge.target)) affectedNodeIds.add(edge.target);
    if (targetChanged && !changedNodeIds.has(edge.source)) affectedNodeIds.add(edge.source);
  }
}

// 4️⃣ Determine impacted layers
const allImpactedIds = new Set([...changedNodeIds, ...affectedNodeIds]);
const affectedLayers = layers.filter(layer =>
  layer.nodeIds.some(id => allImpactedIds.has(id))
);

Using the /understand-diff Skill

Developers can invoke impact analysis through two primary interfaces: direct library consumption or Claude Code integration.

Direct Library Usage

For programmatic access in Node.js environments, import buildDiffContext and formatDiffAnalysis from the skill package:

import { readFile } from "fs/promises";
import { buildDiffContext, formatDiffAnalysis } from "@understand-anything/skill";

// Load the persisted knowledge graph
const graphJson = await readFile("./.understand-anything/knowledge-graph.json", "utf-8");
const graph = JSON.parse(graphJson);

// Example list of changed files from a CI job
const changedFiles = [
  "src/api/userController.ts",
  "src/models/User.ts",
];

// Build the diff context and format a markdown report
const diffCtx = buildDiffContext(graph, changedFiles);
const report = formatDiffAnalysis(diffCtx);

console.log(report);

Claude Code Integration

When used as a Claude Code skill, the system executes autonomously:

  1. Verify presence of .understand-anything/knowledge-graph.json
  2. Execute git diff … --name-only to obtain changed files
  3. Call buildDiffContext(graph, changedFiles) to traverse the graph
  4. Generate markdown via formatDiffAnalysis and write diff-overlay.json for dashboard visualization

Invoke the skill using the command:

/understand-diff

The resulting diff overlay file enables the Understand-Anything dashboard to visualize changed ↔ affected component relationships directly on the interactive graph.

Summary

  • buildDiffContext in src/diff-analyzer.ts drives the three-phase analysis: file-to-node mapping, one-hop edge propagation, and layer aggregation.
  • Impact detection identifies both direct changes and downstream affected nodes by traversing source and target relationships in the graph edge set.
  • Risk assessment automatically flags high-complexity components, cross-layer dependencies, wide blast radii (≥5 affected nodes), and unmapped files.
  • Output artifacts include a structured markdown report for human review and diff-overlay.json for graphical dashboard visualization.
  • Integration options include direct Node.js library imports or autonomous execution via Claude Code agents.

Frequently Asked Questions

How does /understand-diff handle files not present in the knowledge graph?

Files returned by git diff that lack corresponding GraphNode entries are collected in an unmappedFiles array and reported in the final analysis. According to the risk assessment logic in formatDiffAnalysis, unmapped files trigger a specific warning flag, indicating potential blind spots in the architectural model that may require manual review or graph regeneration.

What constitutes a "high risk" assessment in the generated report?

The risk assessment algorithm flags high risk when changes exhibit any of four characteristics: modification of nodes marked with complex status, impact spanning multiple architectural layers, a downstream blast radius affecting five or more nodes, or the presence of unmapped changed files. Changes meeting none of these criteria receive a low-risk classification.

Can the analysis detect transitive dependencies beyond one hop?

The current implementation in src/diff-analyzer.ts performs strictly one-hop propagation from changed nodes to direct neighbors. While the algorithm captures immediate relationships through contains edges and standard dependencies, multi-hop transitive chains require iterative execution or graph preprocessing outside the current buildDiffContext implementation.

Where is the impact analysis output stored for dashboard visualization?

After formatDiffAnalysis generates the markdown report, the skill writes a diff overlay to .understand-anything/diff-overlay.json. This JSON file contains the changed node IDs, affected node IDs, and impacted edge definitions that the Understand-Anything dashboard consumes to highlight affected components in the knowledge graph visualization.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →