Skip to main content
The diff-analyzer module takes a list of changed file paths (e.g. from a git diff) and maps them to the knowledge graph to identify directly changed components, downstream affected components, impacted layers, and cross-cutting relationships. It also generates a risk assessment.

DiffContext

The data structure returned by buildDiffContext.
export interface DiffContext {
  projectName: string;
  changedFiles: string[];
  changedNodes: GraphNode[];
  affectedNodes: GraphNode[];
  impactedEdges: GraphEdge[];
  affectedLayers: Layer[];
  unmappedFiles: string[];
}
projectName
string
required
Name of the analyzed project, taken from graph.project.name.
changedFiles
string[]
required
The original list of changed file paths passed to buildDiffContext.
changedNodes
GraphNode[]
required
Nodes whose filePath matches one of the changed files, plus any nodes contained within those nodes via "contains" edges.
affectedNodes
GraphNode[]
required
1-hop neighbors of changedNodes that are not themselves changed — the downstream blast radius.
impactedEdges
GraphEdge[]
required
All edges where at least one endpoint is a changed node.
affectedLayers
Layer[]
required
Layers that contain at least one changed or affected node.
unmappedFiles
string[]
required
Changed files that could not be matched to any node in the knowledge graph (e.g. new files or deleted files not yet re-analyzed).

buildDiffContext

Maps a list of changed file paths to knowledge graph nodes and identifies the ripple effect (affected nodes, layers, edges).
export function buildDiffContext(
  graph: KnowledgeGraph,
  changedFiles: string[],
): DiffContext
graph
KnowledgeGraph
required
The full knowledge graph produced by the analysis pipeline.
changedFiles
string[]
required
File paths that have changed, as returned by git diff --name-only or similar. Paths should match the filePath values stored on graph nodes.

How it works

  1. File mapping — Each path in changedFiles is matched against node.filePath on every node. Unmatched paths go into unmappedFiles.
  2. Children expansion — For any matched node, edges of type "contains" are followed to include contained child nodes in the changed set.
  3. 1-hop neighbor detection — All edges touching a changed node are collected as impactedEdges. The non-changed endpoint of each edge becomes an affectedNode.
  4. Layer collection — Any layer with a node ID in the union of changed and affected sets is included in affectedLayers.
import { buildDiffContext } from "./diff-analyzer";

const changedFiles = [
  "src/auth/session.ts",
  "src/middleware/rate-limit.ts",
];

const ctx = buildDiffContext(graph, changedFiles);

console.log(ctx.changedNodes.map(n => n.name));
console.log(`Blast radius: ${ctx.affectedNodes.length} components`);
console.log(`Unmapped: ${ctx.unmappedFiles}`);

formatDiffAnalysis

Formats a DiffContext as structured markdown for LLM or human consumption.
export function formatDiffAnalysis(ctx: DiffContext): string
ctx
DiffContext
required
A DiffContext produced by buildDiffContext.

Output structure

The returned string contains the following sections:
SectionContent
## Changed ComponentsName, type, summary, file path, and complexity for each changed node
## Affected ComponentsDownstream neighbors that may need attention
## Affected LayersLayers touched by the change
## Impacted Relationshipssource --[type]--> target for every impacted edge
## Unmapped FilesChanged files not found in the knowledge graph
## Risk AssessmentAutomatically computed risk signals

Risk assessment logic

The risk section is computed automatically from the context:
  • High complexity — emitted when any changed node has complexity === "complex"
  • Cross-layer impact — emitted when affected layers span more than one layer
  • Wide blast radius — emitted when more than 5 nodes are affected downstream
  • New/unmapped files — emitted when unmappedFiles is non-empty
  • Low risk — emitted only when none of the above conditions are met
import { buildDiffContext, formatDiffAnalysis } from "./diff-analyzer";

const ctx = buildDiffContext(graph, changedFiles);
const report = formatDiffAnalysis(ctx);

// Use report as context for an LLM code-review prompt
console.log(report);

Build docs developers (and LLMs) love