CRUMB a card from devarno-cloud

LORE Causality Graph & Decision Visualization

lore advanced 8 min read

ELI5

Imagine a detective board with red string connecting clues. LORE’s Causality Graph does the same for agent decisions — it draws lines between decisions to show which ones influenced which others. This helps humans understand not just what agents decided, but why, and what happened because of it.

Technical Deep Dive

CausalityGraph SVG Primitive

The CausalityGraph is a pure SVG component living at lore/src/components/knowledge/causality-graph.tsx (and reused verbatim in CAIRNET as cairnet/src/components/charts/graph-primitive.tsx). It is:

  • Zero external dependencies — no D3, no Cytoscape.js, no chart library
  • Pure SVG with <circle>, <line>, <text>, and <g> elements
  • Server-compatible — renders in SSR without hydration mismatches (no browser-only APIs)
  • Route-free — the primitive only receives nodes and edges props; navigation is handled by an adapter wrapper

Data Model

The graph reads from pebble’s GET /api/knowledge/graph endpoint, which returns:

interface GraphData {
nodes: {
id: string // decision_id
label: string // short summary
agent_id: string
type: string // decision_type enum
timestamp: string // ISO 8601
}[]
edges: {
source: string // upstream decision_id
target: string // downstream decision_id
relationship: string // "caused_by" | "informed_by" | "conflicts_with"
}[]
}

Graph Layout

The layout is force-directed — computed client-side using a simple iterative repulsion/attraction algorithm (no physics library needed for the small DAGs of decisions, typically <100 nodes). Nodes are coloured by agent role:

  • Coordinator → blue (#a8d8ea)
  • Researcher → purple (#aa96da)
  • Worker → green (#a1e8cc)

Usage Contexts

  1. Decision detail page (/decisions/:id) — Shows a local subgraph: the selected decision, all upstream decisions (what influenced it), and all downstream decisions (what it influenced)
  2. Full graph page (/graph) — Interactive zoomable/pannable full DAG of all decisions
  3. CAIRNET thread graph — Same primitive, different adapter — shows stone reply chains as a thread tree

Adapter Pattern

The CausalityGraph component itself is “LORE-type-free” — it accepts generic GraphNode and GraphEdge types. The LORE-specific adapter (stone-thread-graph.tsx pattern) maps proof_decisions rows into the generic shape. In CAIRNET, a separate adapter maps cairn_stones reply chains into the same generic shape. This is the shared primitive reuse pattern.

Key Terms

  • CausalityGraph → The shared SVG primitive — zero-dependency, pure SVG, route-free
  • GraphNode / GraphEdge → Generic types accepted by the primitive; adapters map domain-specific data into them
  • Adapter pattern → Domain-specific code (LORE decisions, CAIRN stones) maps into generic graph primitives
  • Force-directed layout → Simple iterative repulsion/attraction algorithm for node positioning — no physics library
  • DAG → Directed Acyclic Graph — decisions form a DAG, not a general graph (no circular causality)

Q&A

Q: Why pure SVG instead of D3.js or Cytoscape.js? A: To eliminate bundle bloat, avoid SSR/hydration mismatches, and maintain full control over rendering. The decision DAGs are small enough (<100 nodes) that a complex library is overkill.

Q: How does CAIRNET reuse the same primitive? A: The CausalityGraph component was copied verbatim (not workspace-imported) into cairnet/src/components/charts/graph-primitive.tsx. A CAIRN-specific adapter maps stone reply chains into the generic node/edge interface.

Q: Can the graph be embedded in other dashboards? A: Yes — the primitive is portable. Only an adapter and the generic props interface are needed.

Examples

The CausalityGraph is like Git’s commit DAG visualisation — you can see which commits (decisions) came before which others, trace branches of thought, and find the root of any conclusion.

neighbors on the map