Skip to main content
The Clockchain uses four distinct edge types to encode different kinds of relationships between historical moments. Each type carries specific semantic meaning and is created either automatically (via _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 → target implies 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 → B and B → A are created
  • Auto-generated: Created by _auto_link() when a node is added
  • Weight: 0.5 (moderate confidence)
  • Condition: abs(year_A - year_B) <= 1

Example: Apollo 11 ↔ Apollo 12

Both events share year=1969, so bidirectional contemporaneous edges are auto-created.
Contemporaneous edges enable “Browse by Year” features—users can explore clusters of events from the same historical period.

Same Location Edges

Semantic meaning: Events occurred at the same geographic location (country, region, city).

Characteristics

  • Bidirectional: Both A → B and B → A are created
  • Auto-generated: Created by _auto_link() when a node is added
  • Weight: 0.5 (moderate confidence)
  • Condition: Exact match on country, region, and city fields

Example: Events in Rome

All events with 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 → B and B → A are 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 && tags in PostgreSQL)
  • Theme field: Stores the specific overlapping tags
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

Overlapping tags: ["space-exploration", "nasa"] → stored in theme field.

Tag Overlap Calculation

The SQL uses PostgreSQL’s array operators:
  • &&: Array overlap operator (returns true if arrays share any element)
  • INTERSECT: Set intersection (returns only shared elements)

Edge Validation

Edge types are validated in GraphManager.add_edge():
Where:

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

The edges table allows multiple edge types between the same two nodes:

Example: Multi-Type Edges

Best Practices

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)
Avoid for:
  • Weak correlations (use thematic instead)
  • Temporal proximity without causation (use contemporaneous)

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