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

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, 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) 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 (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 (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 script implements the critical checks:


# 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:

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 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 (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 (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.

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 →