Provenance navigation for knowledge graphs — traverse facts by compass direction with trust decay
In any knowledge system — whether an AI agent's memory, a research database, or a corporate wiki — facts don't exist in isolation. They have provenance: where they came from, what they were derived from, how they've been summarized, and what raw data they were built on. Knowledge Compass organizes these provenance relationships as a navigable graph using a compass metaphor:
- North (↑): Toward the original source — who said it first? What's the primary reference?
- East (→): Toward derivations — what was built from this fact? What conclusions use it?
- South (↓): Toward summaries — condensed, abstracted, or simplified versions
- West (←): Toward the original raw material — the unprocessed data that led to this fact
Each node in the graph carries a trust score that decays with distance from the original source, modeled by a configurable TrustRadius. Navigate the graph step-by-step or find paths between any two facts using BFS.
Provenance is the backbone of trustworthy knowledge systems:
- Fact-checking: Navigate north to verify a claim's source, check trust scores along the way
- Impact analysis: Navigate east from a source to see everything that depends on it — what breaks if this fact is wrong?
- Abstraction: Navigate south to get condensed summaries of detailed information
- Raw data access: Navigate west to retrieve the original measurements, logs, or transcripts
- Trust propagation: Trust decays with distance — derived facts 5 steps from source are less reliable than the source itself
Real-world applications:
- AI agent memory: Agents need to know where their knowledge came from and how trustworthy it is
- Research pipelines: Track how raw experimental data becomes published conclusions
- News verification: Navigate from a headline (south) back to the original source (north)
- Compliance/audit: Prove the provenance chain for regulatory requirements
- Knowledge management: Explore organizational knowledge by following provenance links
┌──────────────────────────────────────────────────────────────┐
│ Knowledge Compass Map │
│ │
│ North (Source) │
│ ↑ │
│ Original ←[W]── [KnowledgeNode] ──[E]→ Derivation │
│ (Raw) │ "The sky appears │ (Downstream) │
│ │ blue due to │ │
│ │ Rayleigh │ │
│ ↓ scattering" ↓ │
│ South (Summary) │
│ "Sky is blue" │
│ │
│ Trust Radius: trust(d) = max(0, 1 - decay×d) │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Source (d=0) ──East──▶ Derived (d=1) ──East──▶ ... │ │
│ │ trust=1.0 trust=0.9 │ │
│ │ │ │
│ │ Source (d=0) ──South─▶ Summary (d=1) ──South─▶ ...│ │
│ │ trust=1.0 trust=0.8 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Navigation: BFS across all directions to find paths │
└──────────────────────────────────────────────────────────────┘
use knowledge_compass::{KnowledgeNode,CompassRose,CompassDirection,Navigation,TrustRadius};// Create a compass rose (knowledge graph)letmut rose = CompassRose::new();// Add a source node (distance 0, trust 1.0)letmut source = KnowledgeNode::new_source("paper-1","Rayleigh scattering causes blue sky");
source.link(CompassDirection::East,"derivation-1");
source.link(CompassDirection::South,"summary-1");
rose.add_node(source);// Add a derived factletmut derived = KnowledgeNode::new_derived("derivation-1","Blue wavelengths scatter most",1,0.9);
derived.link(CompassDirection::West,"paper-1");
rose.add_node(derived);// Add a summaryletmut summary = KnowledgeNode::new_derived("summary-1","Sky appears blue",1,0.8);
summary.link(CompassDirection::North,"paper-1");
rose.add_node(summary);// Navigate: go east from source to see derivationslet nav = Navigation::new(&rose);let derivations = nav.step("paper-1",CompassDirection::East);println!("Derivations: {:?}", derivations.iter().map(|n| &n.fact).collect::<Vec<_>>());// Find a path between any two nodesifletSome(path) = nav.find_path("summary-1","derivation-1"){println!("Path: {:?}", path);// ["summary-1", "paper-1", "derivation-1"]}// Configure trust decaylet trust = TrustRadius::new(10,0.1);// Trust at distance 0 (source): 1.0println!("Trust at d=0: {}", trust.trust_at_distance(0));// Trust at distance 3: 0.7println!("Trust at d=3: {}", trust.trust_at_distance(3));// Trust at distance 10+: 0.0println!("Trust at d=10: {}", trust.trust_at_distance(10));// Check if a node is trusted (trust > 0.1)let node = KnowledgeNode::new_derived("fact","some fact",3,0.7);println!("Is trusted: {}", trust.is_trusted(&node));// Validate and correct a node's trustletmut node = KnowledgeNode::new_derived("fact","wrong trust",3,1.0);let was_valid = trust.validate_trust(&mut node);println!("Was valid: {} (corrected to {:.2})", was_valid, node.trust);// Traverse multiple steps in a directionlet all_derivations = nav.traverse("paper-1",CompassDirection::East,5);println!("All downstream derivations:");for node in&all_derivations {println!(" [d={}, trust={:.2}] {}", node.source_distance, node.trust, node.fact);}// Find all sourceslet sources = rose.sources();println!("{} source nodes in the graph", sources.len());| Variant | Label | Meaning |
|---|---|---|
North | Source | Navigate toward original source |
East | Derivation | Navigate toward downstream uses |
South | Summary | Navigate toward condensed versions |
West | Original | Navigate toward raw material |
| Method | Returns | Description |
|---|---|---|
dir.label() | &str | Human-readable direction name |
dir.opposite() | CompassDirection | Opposite direction |
| Method | Returns | Description |
|---|---|---|
KnowledgeNode::new_source(id, fact) | KnowledgeNode | Source node (distance 0, trust 1.0) |
KnowledgeNode::new_derived(id, fact, distance, trust) | KnowledgeNode | Derived node |
node.link(direction, target_id) | () | Add a provenance link |
node.get_links(direction) | &[String] | Get links in a direction |
node.is_source() | bool | Is this a source (distance 0)? |
| Method | Returns | Description |
|---|---|---|
CompassRose::new() | CompassRose | Create empty graph |
rose.add_node(node) | () | Add a knowledge node |
rose.get(id) | Option<&KnowledgeNode> | Look up by ID |
rose.sources() | Vec<&KnowledgeNode> | All source nodes |
rose.len() | usize | Total nodes |
rose.node_ids() | Vec<&str> | All node IDs |
| Method | Returns | Description |
|---|---|---|
Navigation::new(&rose) | Navigation | Create navigator |
nav.step(from, direction) | Vec<&KnowledgeNode> | One step in a direction |
nav.traverse(from, direction, max_steps) | Vec<&KnowledgeNode> | Multi-step traversal |
nav.find_path(from, to) | Option<Vec<String>> | BFS path between any two nodes |
| Method | Returns | Description |
|---|---|---|
TrustRadius::new(max_distance, decay_rate) | TrustRadius | Configure decay |
tr.trust_at_distance(d) | f64 | Trust at distance d |
tr.is_trusted(node) | bool | Node within trust radius |
tr.validate_trust(&mut node) | bool | Correct trust if inconsistent |
Trust decays linearly with source distance:
trust(d) = max(0, 1 − decay_rate × d)
where d is the shortest path length from the nearest source node. With the default parameters (max_distance=10, decay_rate=0.1):
- d=0: trust=1.0 (source itself)
- d=3: trust=0.7
- d=5: trust=0.5
- d≥10: trust=0.0 (untrusted)
The knowledge graph is a directed multigraph where edges are typed by compass direction:
G = (V, E, label)
V = set of knowledge nodes
E ⊆ V × V × {N, E, S, W}
Direction semantics:
- North edges: from derived → source (provenance chain upward)
- East edges: from source → derivation (impact chain forward)
- South edges: from detailed → summary (abstraction chain)
- West edges: from summary → original (raw data chain)
Navigation uses breadth-first search across all four directions simultaneously, guaranteeing the shortest path in O(V + E) time. Each edge is traversed regardless of direction, treating the graph as undirected for pathfinding purposes.
cargo add knowledge-compassOr add to your Cargo.toml:
[dependencies]
knowledge-compass = "0.1.0"memory-plimpsest— Layered memory with ghost tracesconstellation-map— Fleet visualization as star chartsemotional-colorist— Valence-based color mappingcortex-toml— Configuration-as-code for Exocortex
MIT © SuperInstance
Part of the Exocortex project — persistent cognitive substrate for multi-agent systems.