_auto_link()) or manually (via the Expander or API).
Edge Type Overview
Edge types are enforced at the database level via a
CHECK constraint: type IN ('causes','contemporaneous','same_location','thematic')Causal Edges
Semantic meaning: Node A directly caused or enabled Node B.Characteristics
- Directed:
source → targetimplies causality - Manual only: Never auto-generated (requires human or LLM judgment)
- Weight: Default
1.0(highest confidence) - Created by: Expander worker, manual API calls, or subgraph ingest
Example: Trinity Test → Hiroshima Bombing
Database Constraint
Causal edges are the backbone of the “Rendered Past” — each new causal link tightens the Bayesian prior on what could have happened in historical gaps.
Contemporaneous Edges
Semantic meaning: Events occurred in the same time period (within ±1 year).Characteristics
- Bidirectional: Both
A → BandB → Aare created - Auto-generated: Created by
_auto_link()when a node is added - Weight:
0.5(moderate confidence) - Condition:
abs(year_A - year_B) <= 1
Auto-Link Implementation
Example: Apollo 11 ↔ Apollo 12
year=1969, so bidirectional contemporaneous edges are auto-created.
Same Location Edges
Semantic meaning: Events occurred at the same geographic location (country, region, city).Characteristics
- Bidirectional: Both
A → BandB → Aare created - Auto-generated: Created by
_auto_link()when a node is added - Weight:
0.5(moderate confidence) - Condition: Exact match on
country,region, andcityfields
Auto-Link Implementation
Example: Events in Rome
country="italy", region="lazio", city="rome" are automatically connected.
Location fields use modern political boundaries for consistency. Historical geopolitical entities (e.g., “Roman Empire”) are encoded in tags, not location fields.
Thematic Edges
Semantic meaning: Events share common themes or categories (tag overlap).Characteristics
- Bidirectional: Both
A → BandB → Aare created - Auto-generated: Created by
_auto_link()when a node is added - Weight:
0.3(lowest confidence among auto-links) - Condition: At least one tag in common (
tags && tagsin PostgreSQL) - Theme field: Stores the specific overlapping tags
Auto-Link Implementation
The
theme field captures the specific tags that overlap, allowing fine-grained filtering (e.g., “show me all ‘space-exploration’ edges”).Example: Space Exploration Events
["space-exploration", "nasa"] → stored in theme field.
Tag Overlap Calculation
The SQL uses PostgreSQL’s array operators:&&: Array overlap operator (returnstrueif arrays share any element)INTERSECT: Set intersection (returns only shared elements)
Edge Validation
Edge types are validated inGraphManager.add_edge():
Querying by Edge Type
Get All Causal Edges
Get Neighbors with Edge Metadata
Example Response
Edge Statistics
The/api/v1/stats endpoint provides edge type distribution:
Example Response
contemporaneous edges typically dominate the graph since they’re created for all nodes within ±1 year.Composite Primary Key
Theedges table allows multiple edge types between the same two nodes:
Example: Multi-Type Edges
Best Practices
When to use causal edges
When to use causal edges
Use
causes edges when:- Event A directly enabled Event B (e.g., Trinity Test → Hiroshima)
- A discovery led to a breakthrough (e.g., DNA structure → genetic engineering)
- A political event triggered a war (e.g., assassination → WWI)
- Weak correlations (use
thematicinstead) - Temporal proximity without causation (use
contemporaneous)
Optimizing auto-link performance
Optimizing auto-link performance
Auto-linking uses
INSERT...SELECT for efficiency:- Contemporaneous: O(N) where N = nodes in year ±1
- Same location: O(M) where M = nodes at same location
- Thematic: O(K) where K = nodes with overlapping tags (GIN index accelerates)
- Batching node additions
- Disabling auto-link during bulk imports (add edges separately)
- Using partial indexes on high-cardinality fields
Source Code References
- Edge type validation:
app/core/graph.py:11(constant),app/core/graph.py:180-184(validation) - Auto-link logic:
app/core/graph.py:412-535 - Edge schema:
app/core/db.py:44-51 - Neighbor queries:
app/core/graph.py:317-345