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

> Learn about incremental updates using fingerprint-based change detection in Understand Anything. Optimize project scans by rebuilding only affected knowledge graph components.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: how-to-guide
- Published: 2026-06-10

---

**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`](https://github.com/Egonex-AI/Understand-Anything/blob/main/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`](https://github.com/Egonex-AI/Understand-Anything/blob/main/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`](https://github.com/Egonex-AI/Understand-Anything/blob/main/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`](https://github.com/Egonex-AI/Understand-Anything/blob/main/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:

```typescript
// 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));

```

```typescript
// 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:

- **[`understand-anything-plugin/packages/core/src/fingerprint.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/fingerprint.ts)**: Implements `extractFileFingerprint`, `compareFingerprints`, `buildFingerprintStore`, and `analyzeChanges`
- **[`understand-anything-plugin/packages/core/src/index.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/index.ts)**: Exposes core functions to the plugin ecosystem
- **[`understand-anything-plugin/packages/core/src/change-classifier.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/change-classifier.ts)**: Consumes `ChangeAnalysis` to label files for downstream agents
- **[`understand-anything-plugin/packages/core/src/__tests__/fingerprint.test.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/__tests__/fingerprint.test.ts)**: Validates incremental detection logic including edge cases for new files, deletions, and structural vs. cosmetic classification

## 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`](https://github.com/Egonex-AI/Understand-Anything/blob/main/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`](https://github.com/Egonex-AI/Understand-Anything/blob/main/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.