What if your SPARQL federation engine could learn which data source to ask — and run that decision on a sensor at the edge, in a WASM sandbox, with no JVM behind it?
Today we released OxiRouter 0.1.0 — a Pure Rust Autonomous Semantic Federation Engine for the Edge that performs learned source selection for SPARQL federated queries.
For two decades, federated SPARQL has been the domain of heavy JVM stacks — Apache Jena’s federation, FedX, SPARQL 1.1 SERVICE engines — bolted onto server farms. That works in a datacenter. It does not work on a gateway, a wearable, or inside a browser tab. OxiRouter is different by construction: it is Pure Rust, no_std-capable, compiles to wasm32-unknown-unknown, and ships a tiny edge binary. No JVM. No C. No server farm.
Why OxiRouter matters
Federated querying has a quiet, expensive problem: picking the right endpoint. Send a query blindly to every registered source and you pay a fan-out tax — latency, bandwidth, and wasted compute on sources that were never going to answer. Hard-code a routing table and it rots the moment endpoints change behavior. And the moment you reach for a mature federation engine, you inherit a JVM and a server to host it.
OxiRouter 0.1.0 is an alpha — feature-complete for the 0.1.x line, with an API that may still evolve — but it is already capable where it counts:
- Learned source selection. Given a SPARQL query and a set of registered RDF/SPARQL sources, OxiRouter ranks which source(s) can best answer it — context-aware, with feedback from observed outcomes — instead of fanning out blindly.
- It is small, and it is tested. 23,361 lines of Rust across 96 files, behind 501 unit/integration tests plus 6 doc tests, all passing.
- It runs on the edge. A
release-edgeprofile (fat LTO,opt-level = "z",panic = abort, stripped) pluswasm-opt -Ozproduces a genuinely small WASM router. - It is resilient. A per-source circuit breaker (configurable failure threshold + cooldown) keeps one flaky endpoint from dragging down the whole federation.
- It is context-aware. Four optional “brains” let routing factor in physical location, device, system load, and legal/jurisdiction context.
Edition 2024, MSRV 1.85, Apache-2.0.
Technical Deep Dive
OxiRouter is layered, and almost every layer is an opt-in feature flag so the edge build stays lean.
Core router + pure-Rust semantic-web parsing. src/core/ holds the Router, query, source, and state machinery. Crucially, OxiRouter ships its own pure-Rust parsing rather than pulling a heavyweight semantic-web stack. The sparql feature provides prefix expansion plus SELECT-variable projection extraction (src/core/sparql.rs, with a scanner/parser/property-path AST under src/core/sparql_ast/). The void feature adds a pure-Rust Turtle-subset parser (src/core/turtle.rs) so you can register source capabilities declaratively from a VoID/Turtle descriptor via Router::register_from_void_ttl. This was a deliberate design choice — more on that below.
The ML engine (ml). src/ml/ is a no_std-compatible inference engine (via libm): a neural network (with optional dropout), a naive Bayes classifier, an ensemble, and a federated-learning path — layer, activation, optimizer, schedule, feature, and model modules included. This is what learns the scoring function from your history.
The RL policy (rl). src/rl/ adds reinforcement-learning exploration — ε-greedy, UCB, and Q-learning strategies over a SmallRng — so when a source has little history, OxiRouter can explore intelligently instead of guessing. policy, reward, and feedback modules back the loop.
The four context “brains” (src/context/). Each is feature-gated and backed by a real COOLJAPAN dependency: geo, device, load, and legal, with sensor/provider adapters to feed live context in.
Federation execution (src/federation/). A planner, executor, and aggregator. With the http feature, the executor performs live federation over ureq — synchronous, no async runtime required, which keeps the edge story honest.
WASM bindings (src/wasm/). bindings and context_provider expose the router (and its context providers) to JavaScript via wasm-bindgen + js-sys.
State is durable too: OxiRouter persists with an OXIR wire format — a magic-prefixed binary header followed by a serde_json body — saved and loaded straight from the CLI.
Getting Started
cargo add oxirouter
Or add it to Cargo.toml:
oxirouter = "0.1"
Register a couple of sources, parse a query, and let the router rank them:
use oxirouter::core::source::SourceCapabilities;
use oxirouter::prelude::*;
fn main() -> Result<(), OxiRouterError> {
let mut router = Router::new();
router.add_source(
DataSource::new("dbpedia", "https://dbpedia.org/sparql")
.with_capabilities(SourceCapabilities::full())
.with_vocabulary("http://dbpedia.org/ontology/")
.with_region("EU"),
);
router.add_source(
DataSource::new("wikidata", "https://query.wikidata.org/sparql")
.with_capabilities(SourceCapabilities::full())
.with_vocabulary("http://www.wikidata.org/")
.with_region("EU"),
);
let query = Query::parse(
r"
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?name WHERE {
?person a dbo:Person .
?person dbo:name ?name .
}
LIMIT 100
",
)?;
let ranking = router.route(&query)?;
if let Some(best) = ranking.best() {
println!("Best source: {} (confidence {:.2})", best.source_id, best.confidence);
}
Ok(())
}
The whole point is that routing improves. Close the loop by logging the route and feeding back the outcome:
// Route and record the decision in one step.
let ranking = router.route_and_log(&query)?;
// Later, after the source actually answered, tell the router how it went:
let query_id = query.predicate_hash();
router.learn_from_outcome(query_id, "dbpedia", true, 150, 100)?;
// query_id, source_id, success, latency_ms, result_count
There is also an oxirouter-cli binary with route, explain, void-import, and state save/load subcommands.
What’s inside
Everything in the 0.1.0 line:
- Learned source selection for SPARQL federation — context-aware ranking instead of blind fan-out.
- Pure-Rust SPARQL parser (
sparql): prefix expansion + SELECT-variable projection extraction. - VoID/Turtle source descriptors (
void): a pure-Rust Turtle-subset parser; register sources declaratively withRouter::register_from_void_ttl. - ML inference engine (
ml): neural network, naive Bayes, ensemble, and federated learning —no_std-compatible vialibm; optionaldropout. - RL exploration (
rl): ε-greedy / UCB / Q-learning overSmallRng. - Query log + source statistics with routing-score feedback.
- Per-source circuit breaker: configurable failure threshold + cooldown.
- Cache layer (
cache): in-memory result cache with TTL. - HTTP federation executor (
http): live federation viaureq, synchronous (no async). - WASM bindings (
wasm):wasm-bindgen+js-sys. - Agent action interface (
agent): self-describing primitives for LLM agent runtimes. - Four-brain ecosystem integrations:
geo(OxiGDAL),device(Mielin),load(CeleRS),legal(Legalis-RS). - P2P/IPFS source kind (
p2p): type-level scoring, no network deps. - Observability (
observability): tracing spans + metrics, zero-cost when disabled. - CLI binary (
cli):oxirouter-cli. no_std-capable core (alloc) andOXIRwire-format state persistence.- 501 unit/integration tests + 6 doc tests, all passing.
Tips
A few ways to get the most out of OxiRouter 0.1.0:
- Register sources declaratively. Enable the
voidfeature and feedRouter::register_from_void_ttla VoID/Turtle descriptor instead of hand-codingSourceCapabilities— your topology becomes data, not code. - Close the learning loop. Use
route_and_log()followed bylearn_from_outcome()so the router improves its source selection from real observed latency and success rates. - Turn on the right brains for the job.
ml(neural / naive Bayes / ensemble,no_stdvialibm) sharpens scoring when you have history;rl(ε-greedy exploration) helps when you don’t. - Make routing context-aware. Enable
geo,device,load, andlegalindividually — orecosystemfor all four — so decisions factor in location, device, system load, and jurisdiction. - Build genuinely small for the edge. Try
--no-default-features --features "alloc,wasm,ml,rl,cache"with therelease-edgeprofile andwasm-opt -Ozto ship a tiny WASM router. - Let the circuit breaker protect you. Configure the per-source failure threshold + cooldown so a single flaky endpoint can’t sink your whole federation.
- Expose it to LLM agents. With the
agentfeature,oxirouter.route/.learn/.explainare OpenAI/Anthropic tool-call compatible — drop them straight into an agent’s tool list.
This is the foundation
OxiRouter does not stand alone. Its four context “brains” are real, shipped COOLJAPAN dependencies, each pulled in behind its own feature flag:
geo→ physical context via OxiGDAL (oxigdal-core/oxigdal-proj0.1.4) — geospatial reasoning for location-aware routing.device→ body/device context via Mielin HAL (mielin-hal0.1.0-rc.1).load→ situation context via CeleRS (celers-core0.2.0).legal→ social/jurisdiction context via Legalis-RS (legalis-core0.1.5).
These let a routing decision factor in where you are, what you’re running on, how loaded the system is, and what’s legally permissible — together, the richest part of the OxiRouter story.
And one honest design note, because it’s also a selling point: OxiRouter deliberately does not depend on a full semantic-web stack. The SPARQL prefix-expansion and Turtle-subset parsing are implemented inline in pure Rust (src/core/sparql.rs, src/core/turtle.rs) with zero new dependencies — a lean, edge-friendly choice that keeps the WASM binary tiny and the dependency tree shallow.
Repository: https://github.com/cool-japan/oxirouter
Star the repo if learned, lean, sovereign federation is something you want to see grow — Pure Rust semantic federation is here: learned, lean, and sovereign.
— KitaSan at COOLJAPAN OÜ May 3, 2026