Weave
Graph analysis and image processing NIFs for OSINT knowledge graphs.
Weave is a Cargo workspace that publishes Rust crates to crates.io and an Elixir hex package to hex.pm. The Elixir package uses Rustler to expose Rust functions as NIFs.
Crates
| Crate | Description |
|---|---|
weave-graph | Conflict-of-interest pattern detection on knowledge graphs |
weave-image | Thumbnail download, resize, and WebP conversion |
weave_nif | Rustler NIF bridge (not published, used by the Elixir package) |
Conflict Detection
weave-graph detects six conflict-of-interest patterns (COI-001 through COI-006) using three algorithms:
- Cycle detection -- directed simple cycles matching edge-type sequences (e.g. donation-appointment kickbacks)
- Path detection -- constrained DFS matching edge types and node labels (e.g. family appointments, donor influence chains)
- Hub detection -- Actor-Institution pairs with concentrated influence edges exceeding a threshold
All algorithms operate on in-memory subgraphs extracted from Neo4j with O(1) adjacency lookups. Detection completes in <50ms for subgraphs up to 10K nodes / 50K edges.
Thumbnail Processing
weave-image handles thumbnail generation for entity images:
- Download from URL with 5 MB size limit and 15s timeout
- Center-crop and resize to 256x256 lossless WebP
- Deterministic storage keys via SHA-256 of source URL
- Output capped at 50 KB
Elixir Usage
Add weave to your dependencies:
def deps do
[
{:rbt_weave, "~> 0.2.1"}
]
endA Rust toolchain (1.88+) is required to compile the NIF.
# Verify NIF is loaded
"ok" = Weave.Graph.health_check()
# Detect conflicts (JSON-in, JSON-out)
{:ok, results_json} = Weave.Graph.detect_conflicts(subgraph_json, opts_json)Rust Usage
Add crates to your Cargo.toml:
[dependencies]
weave-graph = "0.2"
weave-image = "0.2"use weave_graph::graph::{Subgraph, IndexedSubgraph};
use weave_graph::detect::{detect_conflicts, DetectOpts};
let subgraph = Subgraph { nodes: vec![/* ... */], edges: vec![/* ... */] };
let indexed = IndexedSubgraph::from_subgraph(&subgraph);
let results = detect_conflicts(&indexed, &DetectOpts::default());Development
# Run Rust tests
cargo test
# Run clippy
cargo clippy --workspace -- -D warnings
# Run Elixir tests
mix deps.get && mix test
# Format
cargo fmt --all --check
mix format --check-formattedLicense
MIT -- see LICENSE for details.