# Fingerprint-Based Change Detection in Egonex-AI Understand-Anything: How It Works

> Discover fingerprint-based change detection in Egonex-AI for efficient code analysis. Learn how it categorizes changes to enable smart knowledge-graph updates.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: deep-dive
- Published: 2026-06-22

---

**Fingerprint-based change detection in Egonex-AI Understand-Anything creates compact structural fingerprints for source files to categorize changes as NONE, COSMETIC, or STRUCTURAL, enabling incremental knowledge-graph updates only when code signatures actually change.**

Egonex-AI/Understand-Anything implements fingerprint-based change detection to optimize knowledge-graph generation by distinguishing between superficial edits and structural modifications. The system generates a compact **structural fingerprint** for every source file, capturing only the elements that affect the knowledge graph—function signatures, class definitions, imports, exports, and a SHA-256 content hash. This approach allows the tool to skip expensive graph rebuilds when only internal logic changes, while ensuring accurate updates when public APIs evolve.

## What Is a Structural Fingerprint?

A **structural fingerprint** is a compact descriptor that captures only the parts of the code that affect the knowledge graph. According to the [`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) implementation, each fingerprint contains:

- Function and class signatures
- Import and export lists
- A SHA-256 hash of the raw file contents

By comparing two fingerprints, the system categorizes changes into three distinct levels without requiring full re-parsing of unchanged files.

## How the Detection Pipeline Works

The fingerprint-based change detection pipeline operates through five distinct phases, orchestrated by the core engine and CLI tools.

### Step 1: Parsing Source Files with TreeSitterPlugin

The process begins when a `TreeSitterPlugin` (or any parser registered in `PluginRegistry`) parses each source file. The parser produces a `StructuralAnalysis` object defined in [`packages/core/src/types.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/types.ts), containing AST-derived lists of functions, classes, imports, and exports. This structural data excludes internal implementation details like variable assignments or loop logic, focusing exclusively on the public API surface.

### Step 2: Generating File Fingerprints

The `extractFileFingerprint()` function in [`fingerprint.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/fingerprint.ts) combines the structural data from the `StructuralAnalysis` object with a SHA-256 hash of the raw file content. This produces a `FileFingerprint` object that serves as the canonical representation of the file's structural state at a specific point in time.

### Step 3: Storing the Baseline

The `buildFingerprintStore()` function iterates over all source files in the project, invoking `extractFileFingerprint()` for each, and aggregates the results into a complete store. The CLI script `skills/understand/build-fingerprints.mjs` drives this operation during a full `/understand` run, persisting the collection to [`.understand-anything/fingerprints.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/.understand-anything/fingerprints.json). This JSON file serves as the baseline for future comparisons.

### Step 4: Detecting Changes

When the project changes, `analyzeChanges()` (also in [`fingerprint.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/fingerprint.ts)) re-creates fingerprints for modified files and invokes `compareFingerprints()` to diff them against the baseline. This produces a `ChangeAnalysis` object that categorizes each file as new, deleted, structurally changed, cosmetic only, or unchanged.

### Step 5: Driving Knowledge-Graph Updates

The change analysis feeds the auto-update pipeline. Only files marked with a **STRUCTURAL** change level trigger a regeneration of the knowledge graph, while **COSMETIC** changes skip the rebuild process entirely. This keeps incremental updates fast and precise.

## Change Categories Explained

The `compareFingerprints()` function categorizes differences into three specific change levels:

- **NONE**: The content hash is unchanged, indicating the file is identical to the baseline.
- **COSMETIC**: The content differs, but structural signatures (functions, classes, imports, exports) remain unchanged. This indicates only internal logic was modified.
- **STRUCTURAL**: One or more signatures changed—such as new or removed functions, altered parameters, or different exports. This requires the knowledge graph to be updated.

## Core Implementation Files

The fingerprint-based change detection system relies on these specific source files:

| File | Role |
|------|------|
| [`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) | Contains `extractFileFingerprint()`, `buildFingerprintStore()`, `analyzeChanges()`, and `compareFingerprints()` |
| `understand-anything-plugin/skills/understand/build-fingerprints.mjs` | CLI entry point that builds the baseline fingerprint store |
| [`understand-anything-plugin/packages/core/src/plugins/registry.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/plugins/registry.ts) | Holds the `PluginRegistry` that coordinates parsers for structural analysis |
| [`understand-anything-plugin/packages/core/src/types.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/types.ts) | Defines `StructuralAnalysis`, `FileFingerprint`, and `ChangeAnalysis` types |

## Generating and Comparing Fingerprints

To generate a baseline fingerprint store, the skills script orchestrates the parsing and storage pipeline:

```typescript
import {
  TreeSitterPlugin,
  PluginRegistry,
  builtinLanguageConfigs,
  registerAllParsers,
  buildFingerprintStore,
  saveFingerprints,
} from '@understand-anything/core';

// Set up parsers
const tsConfigs = builtinLanguageConfigs.filter(c => c.treeSitter);
const tsPlugin = new TreeSitterPlugin(tsConfigs);
await tsPlugin.init();

const registry = new PluginRegistry();
registry.register(tsPlugin);
registerAllParsers(registry);

// projectRoot, sourceFilePaths and gitCommitHash come from the CLI JSON input
const store = buildFingerprintStore(projectRoot, sourceFilePaths, registry, gitCommitHash);

// Persist the baseline
saveFingerprints(projectRoot, store);

```

To detect changes after a commit, load the previous fingerprint store and run the analysis:

```typescript
import {
  PluginRegistry,
  TreeSitterPlugin,
  builtinLanguageConfigs,
  registerAllParsers,
  analyzeChanges,
} from '@understand-anything/core';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';

// Load previous fingerprint store
const previous = JSON.parse(
  readFileSync(join(projectRoot, '.understand-anything/fingerprints.json'), 'utf-8')
);

// Build a registry as before
const registry = new PluginRegistry();
const tsPlugin = new TreeSitterPlugin(builtinLanguageConfigs.filter(c => c.treeSitter));
await tsPlugin.init();
registry.register(tsPlugin);
registerAllParsers(registry);

// `changedFiles` is the set of paths reported by git (or any file-watcher)
const analysis = analyzeChanges(projectRoot, changedFiles, previous, registry);

console.log('Structural changes:', analysis.structurallyChangedFiles);
console.log('Cosmetic only changes:', analysis.cosmeticOnlyFiles);

```

## Summary

- **Fingerprint-based change detection** in Egonex-AI/Understand-Anything uses SHA-256 hashes and AST-derived structural signatures to categorize file changes.
- The system distinguishes between **COSMETIC** changes (internal logic only) and **STRUCTURAL** changes (public API modifications), updating the knowledge graph only when necessary.
- Core functions `extractFileFingerprint()`, `buildFingerprintStore()`, and `analyzeChanges()` in [`fingerprint.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/fingerprint.ts) handle the generation, storage, and comparison operations.
- Baseline fingerprints are stored in [`.understand-anything/fingerprints.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/.understand-anything/fingerprints.json) and generated via the `build-fingerprints.mjs` CLI script.

## Frequently Asked Questions

### What is the difference between a cosmetic change and a structural change?

A **cosmetic change** occurs when the file content differs from the baseline but the structural signatures—function names, class definitions, parameter lists, and import/export statements—remain identical. This typically indicates refactoring of internal logic or formatting changes. A **structural change** occurs when any of these signatures are modified, such as adding a new function, changing a parameter type, or altering an export, which affects the knowledge graph's representation of the codebase.

### How does the system handle different programming languages?

The fingerprint generation relies on the `PluginRegistry` to coordinate language-specific parsers. The `TreeSitterPlugin` processes supported languages by generating a `StructuralAnalysis` object containing the AST-derived elements. Additional parsers can be registered in the registry to support new languages, as long as they conform to the `StructuralAnalysis` interface defined in [`packages/core/src/types.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/types.ts).

### Where are the fingerprint files stored in the project?

The baseline fingerprint store is written to [`.understand-anything/fingerprints.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/.understand-anything/fingerprints.json) in the project root directory. This JSON file contains the complete collection of `FileFingerprint` objects for all source files, along with metadata including the git commit hash. The `saveFingerprints()` utility function handles the serialization and file system operations.

### What triggers a knowledge-graph rebuild?

Only files categorized with a **STRUCTURAL** change level trigger a knowledge-graph rebuild. When `analyzeChanges()` detects structural differences through `compareFingerprints()`, it includes those files in the `structurallyChangedFiles` array. The auto-update pipeline uses this array to determine which files require re-processing, while cosmetic and unchanged files are skipped to minimize computational overhead.