# How Graph-Reviewer Ensures Referential Integrity and Completeness in Knowledge Graphs

> Discover how Graph-Reviewer ensures knowledge graph referential integrity and completeness. Learn about its deterministic two-phase validation process for accurate data.

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

---

**The graph-reviewer agent validates knowledge graphs through a deterministic two-phase process that verifies every reference resolves to an existing node and confirms all required structural elements are present before final approval.**

The graph-reviewer agent serves as the quality gatekeeper in the Egonex-AI/Understand-Anything pipeline, preventing malformed knowledge graphs from reaching downstream consumers. By implementing a strict validation protocol defined in [`understand-anything-plugin/agents/graph-reviewer.md`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/agents/graph-reviewer.md), this component ensures that generated graphs maintain both **referential integrity** (all references resolve) and **completeness** (required structures exist).

## The Two-Phase Validation Architecture

The graph-reviewer operates through a deterministic, two-phase validation process that separates script execution from decision logic.

### Phase 1 – Node.js Validation Script

The agent generates a dedicated **Node.js script** ([`ua-graph-validate.js`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ua-graph-validate.js)) that reads the assembled `KnowledgeGraph` JSON from the pipeline output. This script performs a comprehensive suite of structural checks and writes a structured result file documenting any detected problems. The script exits with code `0` when it runs correctly (even when finding validation errors) and exits with code `1` only when encountering internal execution failures.

### Phase 2 – Review and Decision

After the script completes, the graph-reviewer reads the JSON result file and classifies findings into two categories: **issues** (critical defects) and **warnings** (non-critical observations). The agent emits a final approval object containing `approved: true` only when the `issues` array is empty, ensuring that referential integrity and completeness violations block deployment.

## Enforcing Referential Integrity

Referential integrity ensures that every connection in the knowledge graph points to valid, existing entities.

### Check 2 – Dangling Reference Detection

As implemented in [`understand-anything-plugin/agents/graph-reviewer.md`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/agents/graph-reviewer.md) (lines 63-70), **Check 2** validates that every relationship references real nodes. Specifically, the validator confirms that:
- Every edge `source` and `target` references an existing node `id`
- Every `layer.nodeIds` entry references a valid node ID
- Every tour-step `nodeIds` entry references a valid node ID

Any dangling reference is logged with its specific location in the graph structure, providing precise debugging information for developers.

## Guaranteeing Graph Completeness

Completeness validation ensures the knowledge graph contains the minimum viable structure required for downstream processing.

### Check 3 – Minimum Structural Requirements

According to the specification in [`graph-reviewer.md`](https://github.com/Egonex-AI/Understand-Anything/blob/main/graph-reviewer.md) (lines 71-78), **Check 3** verifies that the graph contains:
- At least one node
- At least one edge
- At least one layer
- At least one tour step

For domain-specific graphs, the absence of layers or tour steps generates warnings rather than critical failures, while nodes and edges remain mandatory requirements across all graph types.

## Additional Structural Safeguards

Beyond core integrity and completeness, the graph-reviewer implements supplementary checks that prevent structural anomalies.

### Layer Coverage and Node Uniqueness

**Layer Coverage** (Check 4) verifies that every file-level node appears in exactly one layer and that no layer contains an empty `nodeIds` array. This prevents orphaned nodes that exist in the graph but remain inaccessible through layer navigation, as well as duplicated node references across layers.

**Uniqueness** (Check 5) detects duplicate node IDs within the graph, ensuring that every identifier represents exactly one entity. These checks reinforce referential integrity by preventing ambiguous references and ensure completeness by validating that every structural element maintains proper coverage.

## Running the Validation

The following example demonstrates how the [`ua-graph-validate.js`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ua-graph-validate.js) script implements the critical checks:

```bash

# 1️⃣ Generate the validation script (illustrative)

cat > .understand-anything/tmp/ua-graph-validate.js <<'EOF'
const fs = require('fs');
const path = process.argv[2];
const out = process.argv[3];
const graph = JSON.parse(fs.readFileSync(path, 'utf8'));
const nodes = new Map(graph.nodes.map(n => [n.id, n]));
const issues = [], warnings = [];

// ---- Referential Integrity (Check 2) ----
graph.edges.forEach((e, i) => {
  if (!nodes.has(e.source)) issues.push(`Edge ${i} source '${e.source}' does not exist`);
  if (!nodes.has(e.target)) issues.push(`Edge ${i} target '${e.target}' does not exist`);
});

// ---- Completeness (Check 3) ----
if (graph.nodes.length === 0) issues.push('Graph has no nodes');
if (graph.edges.length === 0) issues.push('Graph has no edges');
if (!graph.layers?.length) issues.push('Graph has no layers');
if (!graph.tour?.steps?.length) issues.push('Graph has no tour steps');

// (Additional checks omitted for brevity)

fs.writeFileSync(out, JSON.stringify({
  scriptCompleted: true,
  issues,
  warnings,
  stats: {
    totalNodes: graph.nodes.length,
    totalEdges: graph.edges.length,
    totalLayers: (graph.layers||[]).length,
    tourSteps: (graph.tour?.steps||[]).length,
    nodeTypes: Object.fromEntries(Object.entries(
      graph.nodes.reduce((a,n)=>{a[n.type]=(a[n.type]||0)+1;return a},{})
    )),
    edgeTypes: Object.fromEntries(Object.entries(
      graph.edges.reduce((a,e)=>{a[e.type]=(a[e.type]||0)+1;return a},{})
    ))
  }
}, null, 2));
EOF

# 2️⃣ Run the validator on a generated graph

node .understand-anything/tmp/ua-graph-validate.js \
  .understand-anything/knowledge-graph.json \
  .understand-anything/tmp/ua-review-results.json

# 3️⃣ Let the graph-reviewer render the final decision (internal)

# (handled by the agent; you only need the JSON output)

```

## Key Source Files

The validation system relies on these core components:

- **[`understand-anything-plugin/agents/graph-reviewer.md`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/agents/graph-reviewer.md)** – Specification of all validation checks, including referential integrity (lines 63-70) and completeness (lines 71-78)
- **[`understand-anything-plugin/packages/core/src/analyzer/graph-builder.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/analyzer/graph-builder.ts)** – Constructs the `KnowledgeGraph` that the reviewer validates
- **[`understand-anything-plugin/packages/core/src/analyzer/normalize-graph.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/analyzer/normalize-graph.ts)** – Normalizes raw extraction data into the stable graph shape inspected by the reviewer
- **[`understand-anything-plugin/packages/core/src/schema.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/schema.ts)** – Defines the JSON schema used for node/edge type enforcement
- **[`understand-anything-plugin/packages/core/src/search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/search.ts)** – Provides lookup utilities that the validator leverages for reference checks

## Summary

- The graph-reviewer implements a **two-phase validation process** separating script execution from approval logic
- **Referential integrity** is enforced through Check 2, which validates that every edge source/target and layer reference points to an existing node ID
- **Completeness** is guaranteed by Check 3, requiring at least one node, edge, layer, and tour step (with relaxed requirements for domain graphs)
- **Layer Coverage** (Check 4) and **Uniqueness** (Check 5) prevent orphaned nodes and duplicate IDs
- The [`ua-graph-validate.js`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ua-graph-validate.js) script exits with code `0` on successful execution and `1` only on internal failures, producing structured JSON reports for CI/CD integration

## Frequently Asked Questions

### What constitutes a referential integrity violation in the graph-reviewer?

A violation occurs when any edge source or target references a non-existent node ID, or when layer `nodeIds` and tour-step `nodeIds` point to invalid nodes. According to the source specification in [`understand-anything-plugin/agents/graph-reviewer.md`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/agents/graph-reviewer.md) (lines 63-70), the validator checks every reference against the actual node set and logs specific locations for each dangling reference detected.

### How does graph-reviewer distinguish between critical errors and non-critical observations?

The agent classifies findings as either `issues` (critical defects that block approval) or `warnings` (non-critical observations). The final approval object contains `approved: true` only when the `issues` array is empty. For domain graphs, missing tour steps or layers generate warnings rather than critical issues, while nodes and edges remain mandatory requirements across all graph types.

### What are the minimum requirements for graph completeness?

As defined in Check 3 within [`graph-reviewer.md`](https://github.com/Egonex-AI/Understand-Anything/blob/main/graph-reviewer.md) (lines 71-78), a complete knowledge graph must contain at least one node, one edge, one layer, and one tour step. However, for domain-specific graphs, the absence of layers or tour steps triggers warnings rather than hard failures, allowing flexibility while maintaining strict node and edge requirements.

### What exit codes does the ua-graph-validate.js script return?

The script exits with code `0` when it executes successfully, even if it discovers validation problems such as dangling references or missing components. It exits with code `1` only when internal failures prevent the script from running correctly. This distinction allows CI/CD pipelines to differentiate between validation failures (which produce detailed JSON reports) and system execution errors.