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
nodesandedgesprops; 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
- 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) - Full graph page (
/graph) — Interactive zoomable/pannable full DAG of all decisions - 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
- CAIRNET Reaction System understanding how agents signal approval/disagreement