Packages
rbt_weave
0.2.64
0.2.67
0.2.66
0.2.65
0.2.64
0.2.63
0.2.62
0.2.61
0.2.60
0.2.59
0.2.58
0.2.57
0.2.56
0.2.55
0.2.54
0.2.53
0.2.52
0.2.51
0.2.50
0.2.49
0.2.48
0.2.47
0.2.46
0.2.45
0.2.44
0.2.43
0.2.42
0.2.41
0.2.40
0.2.39
0.2.38
0.2.37
0.2.36
0.2.35
0.2.34
0.2.33
0.2.32
0.2.31
0.2.30
0.2.29
0.2.28
0.2.27
0.2.26
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Graph conflict detection and image processing NIFs for OSINT knowledge graphs, powered by Rust.
Current section
Files
Jump to
Current section
Files
README.md
[](https://github.com/redberrythread/weave/actions/workflows/ci.yml)
[](https://github.com/redberrythread/weave/blob/main/LICENSE)
[](https://www.rust-lang.org)
# Weave
Graph analysis, image processing, and content DSL tools for OSINT knowledge graphs.
Weave is a Cargo workspace that publishes Rust crates to [crates.io](https://crates.io) and an Elixir NIF package to [hex.pm](https://hex.pm).
## Packages
| Package | Registry | Version | Description |
| ------- | -------- | ------- | ----------- |
| `weave-graph` | [crates.io](https://crates.io/crates/weave-graph) | [](https://crates.io/crates/weave-graph) | Conflict-of-interest pattern detection |
| `weave-image` | [crates.io](https://crates.io/crates/weave-image) | [](https://crates.io/crates/weave-image) | Thumbnail download, resize, WebP conversion |
| `weave-content` | [crates.io](https://crates.io/crates/weave-content) | [](https://crates.io/crates/weave-content) | Content DSL parser, validator, HTML generator |
| `rbt_weave` | [hex.pm](https://hex.pm/packages/rbt_weave) | [](https://hex.pm/packages/rbt_weave) | Elixir NIF bridge (graph + image) |
## 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. payment-appointment kickbacks)
- **Path detection** -- constrained DFS matching edge types and node labels (e.g. family appointments, payment influence chains)
- **Hub detection** -- Person-Organization 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
## Content DSL
`weave-content` parses, validates, and builds Markdown case files into structured output:
- **Parser** -- YAML front matter + Markdown sections (entities, relationships, timeline, related cases)
- **Validator** -- schema validation, enum enforcement, URL format checks, duplicate detection
- **URL verifier** -- concurrent HEAD/GET checks with caching and configurable concurrency
- **Staleness checker** -- flags cases that may need updates based on status and timeline gaps
- **HTML generator** -- produces semantic HTML fragments for case, entity, tag, and country pages
- **Sitemap generator** -- XML sitemap with cases, entities, countries, and tags
The HTML generator produces fragments (no `<html>`/`<head>` wrapper) with `data-og-*` attributes and Schema.org microdata, suitable for embedding in a Phoenix layout.
### Generated pages
| Page | Path | Description |
| ---- | ---- | ----------- |
| Case | `/cases/{cc}/{type}/{year}/{slug}.html` | Full case with entities, timeline, sources |
| Person | `/people/{cc}/{slug}.html` | Person profile with linked cases |
| Organization | `/organizations/{cc}/{slug}.html` | Organization profile with linked cases |
| Tag (global) | `/tags/{tag}.html` | Cases tagged with a specific tag |
| Tag (country) | `/tags/{cc}/{tag}.html` | Country-scoped tag page |
| Country | `/countries/{cc}.html` | Cases in a specific country |
| Countries index | `/countries.html` | All countries with case counts |
| Tags index | `/tags.html` | All tags with case counts |
| Sitemap | `/sitemap.xml` | Full XML sitemap |
## Elixir Usage
Add `rbt_weave` to your dependencies:
```elixir
def deps do
[
{:weave, "~> 0.2", hex: :rbt_weave}
]
end
```
A Rust toolchain (1.88+) is required to compile the NIF.
```elixir
# 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)
# Country name resolution (249 ISO 3166-1 codes)
"Indonesia" = Weave.Content.country_name("id")
```
## Rust Usage
Add crates to your `Cargo.toml`:
```toml
[dependencies]
weave-graph = "0.2"
weave-image = "0.2"
weave-content = "0.2"
```
```rust
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
```bash
make ci # format check + clippy + test (Rust + Elixir)
cargo test # Rust tests only
mix test # Elixir NIF tests only
```
## License
MIT -- see [LICENSE](LICENSE) for details.