How to Migrate the Egonex Knowledge Graph When Upgrading Plugin Versions

Run maybeMigrateGraph() from @understand-anything/core/staleness to automatically detect version mismatches in .understand-anything/knowledge-graph.json and merge existing user data with new schema requirements, or trigger a complete regeneration when breaking changes are detected.

The Egonex Understand-Anything plugin persists code analysis data to .understand-anything/knowledge-graph.json, but upgrading @understand-anything/* packages can introduce schema changes that invalidate existing graphs. The migration system implemented in packages/core/src/staleness.ts automatically handles additive updates while preserving user-generated nodes and edges, or falls back to full regeneration when breaking changes occur.

How Version Mismatches Trigger Migration

The knowledge graph schema is versioned through the KnowledgeGraph.version field defined in packages/core/src/types.ts (lines 92-94). Each plugin release ships a matching VERSION constant derived from package.json. When loadGraph() executes, it validates the persisted graph against the current Zod schema in packages/core/src/schema.ts (line 422). If graph.version differs from the plugin's expected version, the system flags the graph as stale and initiates the migration workflow.

The Three-Phase Migration Workflow

The migration engine in packages/core/src/staleness.ts processes updates through three distinct phases to ensure data integrity while minimizing unnecessary re-analysis.

Phase 1: Detect Graph Staleness

The core library compares the graph's embedded version string against the plugin's EXPECTED_VERSION constant. This check occurs in packages/core/src/staleness.ts using the graph.version field and determines whether the persisted data matches the current codebase expectations.

Phase 2: Merge or Regenerate

The maybeMigrateGraph function evaluates the version delta to determine the migration strategy:

  • Additive changes (new edge types, optional fields): The system calls mergeGraph(oldGraph, freshGraph) to combine existing user data with the new schema structure, preserving nodes, edges, layers, and tours.
  • Breaking changes (removed fields, renamed types): The helper falls back to a full re-analysis, returning a fresh graph built by packages/core/src/analyzer/graph-builder.ts and wiping the old data.

Phase 3: Persist the Updated Graph

The migrated graph is written back to disk via saveGraph() in packages/core/src/persistence/index.ts (lines 69-78). This routine sanitizes absolute file paths before writing to prevent leaked personal directories in the JSON output.

Step-by-Step Migration Procedure

Follow these steps to programmatically migrate your knowledge graph when upgrading the Egonex plugin.

1. Check the current graph version

import { loadGraph } from "@understand-anything/core";
import { version as pluginVersion } from "@understand-anything/core/package.json";

const graph = loadGraph(projectRoot);
if (graph?.version !== pluginVersion) {
  console.warn(
    `Knowledge graph version (${graph?.version}) differs from plugin version (${pluginVersion}).`
  );
}

2. Execute the staleness helper

import { maybeMigrateGraph } from "@understand-anything/core/staleness";

const updatedGraph = maybeMigrateGraph(projectRoot, graph);

The maybeMigrateGraph implementation in packages/core/src/staleness.ts internally handles the branch logic:

if (graph.version === EXPECTED_VERSION) return graph;          // up-to-date
if (isAdditiveChange(oldVersion, EXPECTED_VERSION)) {
  return mergeGraph(oldGraph, freshGraph);                     // preserve user data
}
// breaking change detected
return freshGraph;                                            // full re-analysis

3. Persist the migrated graph

import { saveGraph } from "@understand-anything/core/persistence";

saveGraph(projectRoot, updatedGraph);

4. Refresh the dashboard

Restart the dev server (pnpm dev:dashboard) or reload the UI. The dashboard will now serve the migrated knowledge-graph.json without schema validation errors.

When to Force a Complete Rebuild

Certain conditions bypass the merge strategy and require full regeneration:

  • Breaking schema changes such as removal of node types, renamed edge types, or required field modifications
  • Major version bumps where the helper treats non-patch version increments as breaking changes
  • Corrupted graph files where validateGraph() in packages/core/src/schema.ts throws validation errors during load

To force a rebuild, delete the persisted graph and rerun analysis:

rm -rf .understand-anything/knowledge-graph.json
understand --full   # re-run the whole pipeline

Summary

  • The graph version field in packages/core/src/types.ts tracks schema compatibility between the persisted JSON and the plugin code.
  • Staleness detection occurs in packages/core/src/staleness.ts via maybeMigrateGraph(), which compares graph.version against the plugin's EXPECTED_VERSION.
  • Additive migrations preserve existing nodes and edges while updating the schema, whereas breaking changes trigger full regeneration via packages/core/src/analyzer/graph-builder.ts.
  • The persistence layer in packages/core/src/persistence/index.ts sanitizes file paths during saveGraph() operations to prevent directory leakage.
  • Use the --full flag to manually regenerate the graph when automatic migration fails or when skipping multiple major versions.

Frequently Asked Questions

What triggers a knowledge graph migration in Egonex?

A migration triggers when the version string inside .understand-anything/knowledge-graph.json does not match the VERSION constant shipped with the current @understand-anything/core package. The loadGraph() function detects this mismatch during initialization and routes the data through maybeMigrateGraph() in packages/core/src/staleness.ts.

How does the migration system preserve existing graph data?

For additive schema changes—such as adding new edge types or optional metadata fields—the mergeGraph() function combines the old graph with a fresh template, retaining user-generated nodes, edges, layers, and tours. This occurs when isAdditiveChange() returns true in packages/core/src/staleness.ts.

Where is the graph version stored and validated?

The version is stored in the KnowledgeGraph.version property defined at lines 92-94 of packages/core/src/types.ts. Validation occurs in packages/core/src/schema.ts (line 422) using a Zod schema that ensures the version string matches the expected format before the migration logic executes.

When should I manually delete and rebuild the graph instead of migrating?

Delete the graph and run understand --full when encountering breaking schema changes (removed fields or renamed types), when upgrading across major versions, or when validateGraph() throws corruption errors. Manual rebuilds ensure the JSON structure aligns perfectly with the new analyzer expectations in packages/core/src/analyzer/graph-builder.ts.

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 →