How the Persistence Layer Saves and Loads the Knowledge Graph JSON in Egonex-AI/Understand-Anything

The persistence layer in Egonex-AI/Understand-Anything writes the knowledge graph to a hidden .understand-anything directory as pretty-printed JSON, sanitizing file paths to remove absolute references before serialization, and validates the structure against a TypeScript schema when loading it back.

The Egonex-AI/Understand-Anything repository provides a robust persistence mechanism that stores analysis results locally while preserving user privacy. Understanding how this layer serializes and deserializes the knowledge graph JSON is essential for developers extending the tool or integrating it into custom workflows. The implementation resides in understand-anything-plugin/packages/core/src/persistence/index.ts and handles everything from directory creation to schema validation.

Where the Persistence Layer Lives

The core persistence logic is centralized in understand-anything-plugin/packages/core/src/persistence/index.ts. This module exports functions for saving and loading the primary knowledge graph, along with auxiliary metadata, fingerprints, configuration, and domain-specific graphs. All persisted files are stored within a hidden folder named .understand-anything located at the project root.

How the Knowledge Graph Is Saved

The saveGraph function orchestrates the write process through three critical steps to ensure portable, privacy-safe storage.

Directory Initialization

Before writing any data, the helper ensureDir(projectRoot) verifies that the .understand-anything folder exists, creating it if necessary. This check runs at lines 13–19 in the persistence index.

Path Sanitization

To prevent leakage of personal directory structures, the sanitiseFilePaths function (lines 38–66) normalizes every node’s filePath before serialization:

JSON Serialization

After sanitization, saveGraph (lines 69–83) calls JSON.stringify(graph, null, 2) to produce pretty-printed JSON and writes the output to knowledge-graph.json using writeFileSync.

How the Knowledge Graph Is Loaded

The loadGraph function (lines 85–104) reverses the process with built-in safety checks.

Validation on Read

By default, loadGraph reads the JSON from disk, parses it, and passes the result through validateGraph imported from packages/core/src/schema.ts. If the structure does not conform to the KnowledgeGraph TypeScript interface defined in src/types.ts, the function throws an error immediately. Developers can bypass validation by passing { validate: false } in the options parameter.

Auxiliary Data Files

The persistence layer manages several companion files alongside the main graph, each following the same ensure-directory-write pattern:

  • meta.json: Stores runtime metadata including timestamps and git hashes (saveMeta/loadMeta, lines 107–115)
  • fingerprints.json: Caches file-level fingerprints for incremental change detection (saveFingerprints/loadFingerprints, lines 118–131)
  • config.json: Holds user-configurable settings (saveConfig/loadConfig, lines 133–148)

Domain-Graph Handling

For higher-level system views, the same sanitization and validation logic is reused for domain-graph.json. The saveDomainGraph and loadDomainGraph functions (lines 152–182) follow identical patterns to the primary graph functions but operate on a separate data structure representing domain-level abstractions.

Practical Code Examples

Saving a Graph After Analysis

import { saveGraph } from '@understand-anything/core/persistence';
import type { KnowledgeGraph } from '@understand-anything/core/types';

async function persist(projectRoot: string, graph: KnowledgeGraph) {
  // Absolute paths are automatically sanitised before writing
  saveGraph(projectRoot, graph);
}

Loading a Graph With Validation

import { loadGraph } from '@understand-anything/core/persistence';
import type { KnowledgeGraph } from '@understand-anything/core/types';

function restore(projectRoot: string): KnowledgeGraph {
  // Throws if JSON is malformed or violates the schema
  return loadGraph(projectRoot);
}

Loading Without Validation

// Use for quick probes or when schema evolution creates temporary mismatches
const graph = loadGraph(projectRoot, { validate: false });

Working with Auxiliary Data

import {
  saveMeta,
  loadMeta,
  saveFingerprints,
  loadFingerprints,
} from '@understand-anything/core/persistence';

// Update last-run timestamp
const meta = loadMeta(projectRoot) ?? { lastAnalyzedAt: '' };
meta.lastAnalyzedAt = new Date().toISOString();
saveMeta(projectRoot, meta);

// Check cached fingerprints
const fingerprints = loadFingerprints(projectRoot);

Summary

Frequently Asked Questions

What happens if the knowledge graph JSON is corrupted?

If the stored JSON is malformed or fails schema validation, loadGraph throws an error immediately. You can skip validation by passing { validate: false } to attempt loading the raw data, though this risks runtime type errors.

Why does the persistence layer sanitize file paths?

Sanitization prevents accidental leakage of developer-specific directory structures such as /Users/alice/... or /home/bob/.... Paths inside the project become relative, while external paths are reduced to filenames only, ensuring the JSON remains portable and privacy-safe when shared.

Can I store the knowledge graph outside the .understand-anything folder?

The current implementation in packages/core/src/persistence/index.ts hardcodes the .understand-anything directory via ensureDir(projectRoot). To use a custom location, you would need to fork the persistence module or use the lower-level sanitiseFilePaths and JSON.stringify logic manually.

Where is the TypeScript schema defined for graph validation?

The validation logic resides in packages/core/src/schema.ts, which exports validateGraph. This validator ensures that loaded objects conform to the KnowledgeGraph interface defined in packages/core/src/types.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 →