Understanding Edge Types and Weight Conventions in Lum1104/Understand-Anything's Knowledge Graph
Lum1104/Understand-Anything defines 35 edge types across eight semantic categories, with weights constrained to [0, 1] to represent relationship strength, where missing values default to 0.5 and out-of-range values are clamped to the nearest bound.
The knowledge graph at the heart of the Understand-Anything project transforms codebases into navigable networks of semantic relationships. To interpret these connections accurately, developers must grasp how edge types categorize relationships and how weights quantify their significance. This guide examines the edge taxonomy, weight semantics, and validation rules implemented in the Lum1104/Understand-Anything repository.
Edge Type Taxonomy in Understand-Anything's Knowledge Graph
The complete list of edge types lives in packages/core/src/types.ts, implemented as a TypeScript union type called EdgeType. These 35 distinct types are grouped into eight semantic categories that capture everything from code structure to domain knowledge.
The definition groups edges as follows:
// Edge types (35 total in 8 categories)
export type EdgeType =
// Structural
| "imports" | "exports" | "contains" | "inherits" | "implements"
// Behavioral
| "calls" | "subscribes" | "publishes" | "middleware"
// Data flow
| "reads_from" | "writes_to" | "transforms" | "validates"
// Dependencies
| "depends_on" | "tested_by" | "configures"
// Semantic
| "related" | "similar_to"
// Infrastructure / Schema
| "deploys" | "serves" | "provisions" | "triggers"
// Schema / Data
| "migrates" | "documents" | "routes" | "defines_schema"
// Domain
| "contains_flow" | "flow_step" | "cross_domain"
// Knowledge
| "cites" | "contradicts" | "builds_on" | "exemplifies"
| "categorized_under" | "authored_by";
All edge type strings are validated by zod in packages/core/src/schema.ts within the EdgeTypeSchema. If an edge is missing a type, the validator auto-corrects it to "depends_on" and records an issue.
Structural and Behavioral Relationships
Structural edges model containment and inheritance hierarchies. The contains type indicates that a file or module encapsulates a function or class, while inherits and implements capture object-oriented relationships. Behavioral edges such as calls, subscribes, and publishes map runtime interactions like function invocations and event-driven communication patterns.
Data Flow and Dependencies
Data flow edges track how information moves through the system. The reads_from and writes_to types link functions to data sources, while transforms and validates indicate processing stages. Dependency edges like depends_on and tested_by express service relationships and testing coverage, often assigned higher weights to reflect critical path connections.
Semantic and Domain-Specific Connections
Higher-level relationships include related and similar_to for semantic similarity, cross_domain for boundary crossings in domain-driven design, and knowledge-graph primitives like cites and builds_on for documentation and research contexts. These edges typically carry lower weights (0.2–0.4) to indicate loose coupling compared to structural containment.
Edge Weight Conventions and Validation Rules
Every edge in the knowledge graph carries a weight: number field constrained to the closed interval [0, 1] as defined in GraphEdgeSchema within packages/core/src/schema.ts. The weight quantifies the strength or confidence of the relationship:
- 0.0–0.2: Weak or optional relations (e.g., loose references or semantic similarity)
- 0.3–0.6: Moderate confidence (common imports, typical function calls)
- 0.7–1.0: Strong or deterministic relations (containment, direct calls, explicit dependencies)
Auto-Correction and Normalization
When deserializing a graph, the validation pipeline in packages/core/src/schema.ts enforces strict normalization rules:
- Missing weight: Defaulted to
0.5(mid-range) and recorded as an auto-corrected issue - String weight: Coerced to a number; invalid strings fall back to
0.5 - Out-of-range values (e.g.,
-0.1or1.5): Clamped to the nearest bound (0or1) with an issue logged
These conventions guarantee that downstream consumers—such as the dashboard layout algorithms and LLM-driven explanations—always receive a numeric weight they can safely use for ranking or filtering.
Edge Directionality Semantics
Edges carry a direction field with three allowed values:
direction: "forward" | "backward" | "bidirectional"
During deserialization, the validator normalizes aliases such as "TO" to "forward". Forward edges point from source to target, backward edges represent the inverse relationship, and bidirectional edges render as two-way links in the UI. Directionality is critical for pathfinding algorithms and for correctly interpreting relationships like imports versus exports.
Practical Applications of Edge Weights
Edge weights influence multiple subsystems throughout the Understand-Anything codebase:
- Layout algorithms: The dashboard's
utils/layout.tsandutils/louvain.tscompute community detection and force-directed placement using weights to influence edge length—stronger edges draw nodes closer together - Explanation generation:
src/explain-builder.tsfilters and ranks edges by weight when assembling human-readable narratives, prioritizing high-confidence relationships (≥ 0.7) - Diff analysis:
src/diff-analyzer.tspropagates changes through high-weight edges first, treating them as more impactful to the system's behavior
Working with GraphEdge in Code
The following examples demonstrate how to construct edges, handle validation, and utilize weights in custom algorithms.
Constructing a Type-Safe Edge
import { GraphEdge } from "@understand-anything/core";
const edge: GraphEdge = {
source: "file:src/auth.ts",
target: "function:src/auth.ts:login",
type: "contains", // structural containment
direction: "forward",
description: "auth file contains login function",
weight: 1.0, // strongest possible link
};
Validating Raw Input with Auto-Correction
import { validateKnowledgeGraph } from "@understand-anything/core";
const raw = {
source: "file:src/service.ts",
target: "file:src/db.ts",
type: "reads_from",
// direction omitted → defaults to "forward"
// weight omitted → defaults to 0.5 (auto-corrected)
};
const { data, issues } = validateKnowledgeGraph({
version: "1.0",
project: {/*…*/},
nodes: [],
edges: [raw],
layers: [],
tour: []
});
console.log(data.edges[0].direction); // "forward"
console.log(data.edges[0].weight); // 0.5
console.log(issues[0].message); // edges[0]: missing "direction" — defaulted to "forward"
Using Weights in Layout Algorithms
import { GraphEdge } from "@understand-anything/core";
function computeEdgeLength(edge: GraphEdge): number {
// Stronger edges are drawn shorter (more tightly) – inverse mapping
const minLen = 30, maxLen = 200;
return maxLen - edge.weight * (maxLen - minLen);
}
// Example usage:
const short = computeEdgeLength({
weight: 1,
source: "",
target: "",
type: "contains",
direction: "forward"
});
const long = computeEdgeLength({
weight: 0.2,
source: "",
target: "",
type: "related",
direction: "forward"
});
console.log(short, long); // 30 170
Filtering by Confidence Threshold
import { GraphEdge } from "@understand-anything/core";
function topEdges(edges: GraphEdge[], threshold = 0.7) {
return edges.filter(e => e.weight >= threshold);
}
const important = topEdges(sampleGraph.edges);
console.log(important.map(e => `${e.source} → ${e.target} (${e.weight})`));
Summary
- 35 edge types in eight categories (structural, behavioral, data-flow, dependencies, semantic, infrastructure, schema, and knowledge) are defined in
packages/core/src/types.ts - Weight values must fall within [0, 1], where higher values indicate stronger relationships; the system defaults missing weights to
0.5and clamps out-of-range values - Validation occurs in
packages/core/src/schema.tsusing zod schemas that auto-correct missing types to"depends_on"and normalize direction strings - Directionality supports forward, backward, and bidirectional relationships, with normalization for legacy aliases
- Downstream systems leverage weights for force-directed layout in
utils/layout.ts, explanation ranking inexplain-builder.ts, and impact analysis indiff-analyzer.ts
Frequently Asked Questions
What are the 35 edge types in Understand-Anything?
The 35 edge types span eight semantic categories defined in packages/core/src/types.ts. Structural types include imports, exports, contains, inherits, and implements. Behavioral types cover calls, subscribes, publishes, and middleware. Data flow is captured by reads_from, writes_to, transforms, and validates. Additional categories handle dependencies (depends_on, tested_by), infrastructure (deploys, serves), schema (defines_schema, migrates), domain logic (cross_domain, flow_step), and knowledge relationships (cites, builds_on).
How does Understand-Anything handle missing edge weights?
When an edge lacks a weight field, the validator in packages/core/src/schema.ts assigns a default value of 0.5 and logs an auto-correction issue. If the weight is provided as a string, the system attempts to coerce it to a number; invalid strings also fall back to 0.5. Values outside the [0, 1] range are clamped to the nearest valid bound (0 or 1) rather than rejected.
What is the difference between forward and bidirectional edges?
Forward edges represent relationships that flow from source to target, such as a file importing another module or a function calling another function. Bidirectional edges indicate mutual relationships where both nodes influence each other equally, such as two services in a circular dependency or semantically similar concepts. The UI renders forward edges as single arrows and bidirectional edges as double-headed links.
How are edge weights used in the dashboard layout?
The dashboard's layout engine in packages/dashboard/src/utils/layout.ts uses edge weights to compute force-directed graph distances. Higher weights (closer to 1.0) result in shorter edge lengths, pulling connected nodes tightly together. Lower weights allow greater separation. This visual encoding helps users immediately distinguish strong structural dependencies from weak semantic associations.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →