Incremental Updates with Fingerprint-Based Change Detection in Understand-Anything

Understand-Anything accelerates project scans by generating structural fingerprints via Tree-Sitter analysis, classifying changes as NONE, COSMETIC, or STRUCTURAL to rebuild only the knowledge graph components affected by signature modifications.

The Egonex-AI/Understand-Anything repository implements a high-performance incremental update system that eliminates redundant knowledge graph rebuilds across large codebases. By extracting semantic fingerprints from source files using Tree-Sitter parsing, the system distinguishes between superficial formatting changes and modifications that actually alter code relationships. This fingerprint-based change detection mechanism lives in the understand-anything-plugin/packages/core package and enables near-instantaneous incremental scans by filtering files through a conservative three-tier classification algorithm.

How Structural Fingerprints Capture Code Semantics

Fingerprint Generation with Tree-Sitter

The extractFileFingerprint function (L79-L121 in understand-anything-plugin/packages/core/src/fingerprint.ts) processes each source file through Tree-Sitter to build a FileFingerprint object. This structure captures function signatures, class definitions, imports, and exports—essentially every element that affects the knowledge graph topology.

Content Hashing for Integrity

Alongside structural data, the contentHash function (L70-L71) generates a SHA-256 hash of the raw file content. This dual-layer approach allows the system to detect any file modification while separately evaluating whether that modification impacts the semantic structure.

The Three-Tier Change Classification System

The compareFingerprints function (L31-L44) implements the core classification algorithm that categorizes differences into three severity levels:

  1. NONE: The content hash matches exactly, indicating identical files.
  2. COSMETIC: The content hash differs but structural analysis (function names, signatures, class members, imports, exports) remains identical, indicating formatting or comment changes.
  3. STRUCTURAL: Any mismatch in semantic elements or missing structural analysis for either version, indicating changes that affect the knowledge graph.

This conservative approach ensures that files lacking Tree-Sitter support (which receive hash-only fingerprints) automatically trigger STRUCTURAL classification, preventing false negatives in dependency analysis.

Building and Persisting the Fingerprint Store

The buildFingerprintStore function (L48-L90) orchestrates the initial indexing of a project. It traverses the entire codebase, invokes Tree-Sitter analysis via the plugin registry for each file, and writes a fingerprints.json file containing:

  • Individual file fingerprints with structural data and content hashes
  • A project-wide gitCommitHash for versioning context

Files without Tree-Sitter grammar support receive hash-only entries, forcing structural reprocessing on any detected change to ensure safety.

Executing Incremental Analysis

The Change Detection Workflow

When a new scan initiates, the analyzeChanges function (L97-L141) orchestrates the incremental update:

  1. Reads the existing fingerprint store from fingerprints.json
  2. Identifies modified files via Git diff
  3. Re-analyzes only changed files using Tree-Sitter
  4. Runs compareFingerprints against stored versions
  5. Returns a ChangeAnalysis object categorizing results

The ChangeAnalysis Output

The analysis produces a structured report consumed by understand-anything-plugin/packages/core/src/change-classifier.ts and the dashboard:

  • newFiles and deletedFiles: Always classified as STRUCTURAL
  • structurallyChangedFiles: Files with signature or definition modifications requiring knowledge graph rebuilds
  • cosmeticOnlyFiles: Content changes requiring only UI refresh
  • unchangedFiles: Identical content skipped entirely

The dashboard uses this output to determine whether to re-render the knowledge graph or simply refresh file views, optimizing performance by avoiding expensive graph reconstructions for cosmetic edits.

Implementation Examples

The following patterns demonstrate building the initial store and running incremental updates:

// Build the initial fingerprint store (run once per project)
import { buildFingerprintStore } from "./fingerprint.js";
import { registry } from "./plugins/registry.js";

const allFiles = [...];                     // discovered source files
const store = buildFingerprintStore(
  "/my/project",
  allFiles,
  registry,
  "a1b2c3d4"                                // git commit hash
);
writeFileSync("fingerprints.json", JSON.stringify(store));
// On a subsequent scan, detect only the changed files
import { analyzeChanges } from "./fingerprint.js";

const changed = ["src/utils.ts", "src/new-module.ts"]; // from git diff
const previous = JSON.parse(readFileSync("fingerprints.json", "utf-8"));
const analysis = analyzeChanges(
  "/my/project",
  changed,
  previous,
  registry
);

console.log(analysis.structurallyChangedFiles); // Files that reshape the graph
console.log(analysis.cosmeticOnlyFiles);       // Files needing UI refresh only

Key Files in the Implementation

The incremental update system spans several critical files in the repository:

Summary

  • Fingerprint-based change detection in Understand-Anything uses Tree-Sitter to extract semantic signatures from source files, storing function definitions, class structures, and imports alongside SHA-256 content hashes.
  • The compareFingerprints function classifies changes into NONE, COSMETIC, or STRUCTURAL tiers, ensuring only semantic modifications trigger expensive knowledge graph rebuilds.
  • Incremental analysis via analyzeChanges processes only files reported by Git diff, comparing fresh fingerprints against the stored fingerprints.json to minimize computational overhead.
  • Files lacking Tree-Sitter support receive hash-only fingerprints, forcing STRUCTURAL classification to maintain analysis safety.
  • The system outputs a ChangeAnalysis object that directs the dashboard to either re-render graph relationships or perform lightweight UI refreshes based on change severity.

Frequently Asked Questions

What triggers a STRUCTURAL versus COSMETIC change classification?

A STRUCTURAL change occurs when compareFingerprints detects any difference in function signatures, class definitions, imports, or exports between the stored and current fingerprints, or when structural analysis is unavailable for either version. COSMETIC changes happen when the SHA-256 content hash differs but all structural elements remain identical, indicating formatting, whitespace, or comment modifications that do not affect the knowledge graph.

How does the system handle files without Tree-Sitter support?

Files lacking Tree-Sitter grammar support receive hash-only fingerprints from buildFingerprintStore. Because no structural metadata exists for comparison, the system conservatively classifies any detected change as STRUCTURAL, ensuring the knowledge graph updates safely when the content of unsupported files changes.

Where is the fingerprint data stored between scans?

The buildFingerprintStore function writes fingerprint data to a JSON file named fingerprints.json in the project directory. This store contains the content hash, structural analysis data, and project-wide gitCommitHash for each source file, enabling analyzeChanges to perform comparisons during subsequent incremental scans.

What is the performance benefit of fingerprint-based incremental updates?

By filtering files through the NONE, COSMETIC, and STRUCTURAL classification system, Understand-Anything avoids rebuilding the entire knowledge graph on every scan. Only files with STRUCTURAL changes undergo full graph reconstruction, while COSMETIC changes trigger lightweight UI refreshes and NONE changes are skipped entirely, enabling near-instantaneous updates on large repositories.

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 →