How Does the Diff Impact Analysis Feature (/understand-diff) Work in Understand-Anything?
The /understand-diff command analyzes Git diffs by mapping changed files to knowledge graph nodes, propagating impact through one-hop dependencies, and generating a markdown risk assessment of downstream effects.
The diff impact analysis feature in the Understand-Anything toolkit enables developers to evaluate the ripple effects of code changes without manual codebase inspection. By feeding a Git diff or pull request into the knowledge graph, the system identifies affected components, calculates risk levels, and produces structured reports for both human review and LLM consumption. This functionality centers on two core functions exported from the plugin's analyzer module.
Core Architecture and Data Flow
The feature implements an eight-step pipeline defined in understand-anything-plugin/skills/understand-diff/SKILL.md and executed through the buildDiffContext function in understand-anything-plugin/src/diff-analyzer.ts. The process transforms raw file changes into a comprehensive impact graph suitable for architectural review.
Input Processing and Node Mapping
The pipeline begins when the skill obtains a list of changed file paths from the Git diff (typically via git diff --name-only). The buildDiffContext function iterates over these paths and searches the graph's nodes array for matching node.filePath values. Files that successfully match become changed nodes, while orphaned paths are recorded in unmappedFiles for later risk assessment.
According to the source code in diff-analyzer.ts (lines 31-42), this mapping establishes the foundation for all subsequent impact analysis by anchoring the diff to the knowledge graph's node structure.
Containment Expansion and Impact Propagation
After direct mapping, the analyzer performs containment expansion to capture internal components. The function traverses contains edges to identify child nodes—such as functions or classes within a changed file—ensuring that modifications to a parent file surface all internal symbols that may require review (lines 44-49).
Next, the system executes one-hop impact propagation (lines 57-69). The analyzer scans every edge in the graph; if either endpoint connects to a changed node, the edge is added to impactedEdges and the opposite endpoint joins the affected nodes set. This bidirectional traversal captures both upstream callers and downstream dependencies, creating a complete blast radius of the change.
Layer Aggregation and Context Assembly
With changed and affected nodes identified, the function aggregates affected layers by filtering the graph's layers array to include only those referencing nodes in the combined ID set (lines 74-77). The final DiffContext object (lines 79-87) encapsulates:
- Project metadata and raw file list
- Arrays of changed and affected nodes
- Impacted edge relationships
- Affected architectural layers
- Unmapped files requiring manual review
Source Code Implementation
The analyzer's logic resides in understand-anything-plugin/src/diff-analyzer.ts, which exports two primary functions consumed by the skill definition:
buildDiffContext– Implements the graph traversal logic, node mapping, and layer aggregation described in the architectural walkthrough.formatDiffAnalysis– Renders theDiffContextas structured markdown, including risk assessment calculations.
These functions are re-exported through understand-anything-plugin/src/index.ts to ensure availability for the skill implementation defined in SKILL.md.
Practical Usage Example
You can invoke the diff impact analysis programmatically using the exported functions:
import { readFile } from "node:fs/promises";
import { buildDiffContext, formatDiffAnalysis } from "@understand-anything/skill";
// Load the persisted knowledge graph
const graph = JSON.parse(
await readFile("./.understand-anything/knowledge-graph.json", "utf-8"),
);
// Define changed files (normally from git diff)
const changedFiles = ["src/service.ts", "src/routes.ts"];
// Build the diff context
const ctx = buildDiffContext(graph, changedFiles);
// Generate human-readable markdown report
const markdown = formatDiffAnalysis(ctx);
console.log(markdown);
Executing this snippet against the test suite graph (see diff-analyzer.test.ts) produces a markdown report containing Changed Components, Affected Components, Affected Layers, and Risk Assessment sections.
Risk Assessment and Dashboard Integration
The formatDiffAnalysis function (lines 93-195) constructs the final output through several markdown sections:
- Changed Components – Directly modified files and their contained symbols
- Affected Components – Nodes within the one-hop dependency radius
- Affected Layers – Architectural layers touched by the changes
- Impacted Relationships – Edges connecting changed and affected nodes
- Unmapped Files – Changed paths not found in the knowledge graph
The Risk Assessment section evaluates four specific factors: node complexity metrics, cross-layer dependency count, total blast radius size, and the presence of unmapped files that might indicate coverage gaps.
According to SKILL.md (lines 61-70), the skill additionally writes a JSON overlay to .understand-anything/diff-overlay.json, enabling the dashboard to visually highlight changed and affected nodes for interactive exploration.
Summary
- The
/understand-diffcommand leveragesbuildDiffContextindiff-analyzer.tsto map Git diffs onto the knowledge graph. - Containment edges expand file changes to include internal symbols, while one-hop edge traversal identifies upstream and downstream dependencies.
- The system aggregates affected architectural layers and calculates risk based on complexity, cross-layer dependencies, and unmapped files.
- Output is rendered via
formatDiffAnalysisas structured markdown and supplemented by a JSON overlay for dashboard visualization. - All functionality is tested in
diff-analyzer.test.ts, which documents expected behavior for node detection and impact propagation.
Frequently Asked Questions
How does the analyzer handle files not present in the knowledge graph?
Files that do not match any node.filePath in the graph are collected in the unmappedFiles array within the DiffContext. These unmapped files contribute to the risk assessment, as they represent changes that cannot be analyzed for downstream impact, potentially indicating gaps in the knowledge graph coverage or new files requiring ingestion.
What types of relationships does the diff impact analysis traverse?
The analyzer specifically examines contains edges to expand parent files into their child symbols (functions, classes), and general edges for one-hop impact propagation. The one-hop traversal is bidirectional, capturing both dependencies pointing to changed nodes (callers) and dependencies originating from changed nodes (callees), ensuring comprehensive blast radius detection.
Can I use the diff analyzer outside of the CLI skill interface?
Yes. The buildDiffContext and formatDiffAnalysis functions are exported from understand-anything-plugin/src/index.ts and can be imported programmatically into any TypeScript or JavaScript application. You must provide a valid knowledge graph object and an array of changed file paths, allowing integration into CI/CD pipelines, custom IDEs, or automated code review systems.
Where is the risk level calculated in the source code?
The risk assessment logic resides in formatDiffAnalysis within diff-analyzer.ts (lines 158-195). The function evaluates node complexity, counts cross-layer dependencies, measures the total blast radius (number of affected nodes), and checks for unmapped files to generate a qualitative risk rating included in the markdown output.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →