Provenance and Licensing

gridoxide's own code is licensed under Apache-2.0 (LICENSE). Several pieces of third-party code are vendored, translated, or linked, and each carries its own terms. This page is the summary; the authoritative per-file detail lives in the PROVENANCE.md files kept alongside the code they describe.

The crate-wide license field

Cargo.toml's license field is:

Apache-2.0 AND BSD-3-Clause AND LGPL-2.1-or-later

That is accurate for every default cargo build, not just an opt-in one — because crates/gridoxide-sparse/src/klu_native/ is always built, with no feature gate.

Always built: crates/gridoxide-sparse/src/klu_native/

crates/gridoxide-sparse/src/klu_native/ is a from-scratch Rust translation of vendored SuiteSparse AMD, BTF, and KLU C source. A close translation of licensed source is reasonably a derivative work regardless of implementation language, so it carries forward its upstream license — and that is not one license here:

Upstream packageLicenseTranslated into
AMDBSD-3-Clauseamd/aat.rs, amd/core.rs, amd/postorder.rs, amd/mod.rs
BTFLGPL-2.1-or-laterbtf/maxtrans.rs, btf/strongcomp.rs, btf/mod.rs
KLULGPL-2.1-or-lateranalyze.rs, kernel.rs, factor.rs, scale.rs, refactor.rs, solve.rs

crates/gridoxide-sparse/src/klu_native/PROVENANCE.md has the exact file-by-file mapping back to the upstream C, including which specific functions each Rust file was ported from and how shared header material was classified. See Inside KLU for what the ported algorithm actually does.

Opt-in: --features klu

Building with cargo build --features klu additionally compiles the vendored SuiteSparse C itself into the binary via FFI. crates/gridoxide-sparse/vendor/suitesparse/ is a partial vendoring of SuiteSparse at tag v7.12.2 (commit 42151688813c45846a597edcb601435a0e38f3dd, 2026-02-10) — only the Source/ and Include/ subdirectories of five packages (SuiteSparse_config, AMD, COLAMD, BTF, KLU), each keeping its own Doc/License.txt:

PackageLicense
AMDBSD-3-Clause
COLAMDBSD-3-Clause
BTFLGPL-2.1-or-later
KLULGPL-2.1-or-later
SuiteSparse_configBSD-3-Clause

This adds no license beyond what is already listed above, but it does add LGPL's relinking obligations for anyone distributing a binary built with that feature. The klu-dynamic sub-feature exists for that case: it links a system-installed libklu.so instead of statically linking the vendored copy. See crates/gridoxide-sparse/vendor/suitesparse/PROVENANCE.md for exactly what was and was not vendored, and how to update to a newer SuiteSparse release.

Opt-in: --features pardiso

A separate case from all of the above. It dynamically links a locally-installed Intel oneMKL (libmkl_rt.so) at build and run time, under Intel's own Simplified Software License — not LGPL, not OSS, and not vendored or redistributed by this repo in any form. No MKL header or source is copied in; bindgen only reads the local install's own mkl_pardiso.h at build time to generate FFI bindings.

Because nothing MKL-derived is ever copied into or shipped by this crate, Cargo.toml's license field does not change for this feature. Anyone who builds with --features pardiso and distributes the resulting binary is responsible for their own compliance with Intel's oneMKL redistribution terms — this project doesn't audit that on their behalf.

Opt-in: --features cgmes — the cimoxide dependency

The optional cgmes feature (src/cgmes.rs) depends on cimoxide's model crate, a separate Rust project by the same author providing CGMES RDF/XML decoding. Each decoded object is an Element — its class, its mRID and its fields as written, read by Class.attr key — checked against class tables generated from ENTSO-E's schemas.

cimoxide is Apache-2.0, matching gridoxide's own license — no licensing mismatch from this dependency.

The package = rename

cimmodel = { package = "cimoxide-model", version = "0.6.0", optional = true }

The crate's library is named cimmodel, so the code says cimmodel::CimDataset whatever the package is called; package = makes the dependency's name match it.

Formerly typed structs

Up to 0.3, cimoxide published cimoxide-decoder and cimoxide-structs: one generated Rust struct per CIM class, read by field (line.r). 0.4 merged them into cimoxide-model and replaced the structs with Elements read by key (line.get_f64("ACLineSegment.r")). A key names the class that declares the attribute, so a breaker's open is Switch.open. The compiler no longer checks a key: a misspelt one reads as absent, the same as an attribute the file leaves out. The CGMES tests are what catch one.

Formerly a git dependency

Until cimoxide's crates.io release, its crates were a git dependency pinned to a vendor/gridoxide branch — main plus one commit force-adding the code generator's normally-gitignored output, since the generated source is produced by cargo run -p cimgen from ENTSO-E's RDF/SHACL schemas and so did not exist on a fresh main clone.

Updating

To pick up a newer cimoxide schema or generator change:

  1. Release the new version from the cimoxide repo (make generate, then make build && make test before publishing — the generated class tables are what a schema change moves).
  2. Bump the version = value in this repo's Cargo.toml for the cimmodel dependency, and update the version noted above.
  3. Run cargo build --features cgmes and cargo test --features cgmes to confirm the converter still matches tests/cgmes_microgrid_be_test.rs's expectations — CGMES attribute names could change between schema versions, and a renamed one compiles and reads as absent. The fixture-backed CGMES tests silently skip when tests/data/CGMES-Test-Configurations isn't checked out, so git submodule update --init tests/data/CGMES-Test-Configurations first, or the run proves nothing beyond "it compiles".

Test fixtures

The CGMES conformance fixtures under tests/data/cgmes/ are referenced via a git submodule rather than committed, because of their own licensing — see tests/data/cgmes/README.md.

The UCTE, IIDM and CRAC files the importer and remedial-action tests read, and the Cucumber suite of the external gate, come from powsybl-open-rao and carry its MPL-2.0 licence. They are not in this repository. They live in the benchmark-grids submodule under powsybl-open-rao/, pinned to an upstream commit, with that repository's PROVENANCE.md giving the upstream path of each part. tests/data/openrao-fixtures.txt names the files the tests use outside the gate, and tests/data/rao/*.txt select the gate's scenarios by id.

What this repository does keep is its own work: those scenario lists, and the pypowsybl reference solutions under tests/data/ucte/ and tests/data/iidm/, which gridoxide generated with scripts/bench/{ucte,iidm}_reference.py. MPL-2.0 is a per-file copyleft and does not reach the code that reads the files, so Cargo.toml's license field is unaffected either way.

Worth separating from that: src/ucte.rs itself is not a translation of powsybl-open-rao or of powsybl-core's ucte-network module. The column positions and the tap-changer formulae in it were established from the format specification and then verified against those implementations — the .pypowsybl.json files record the verification. Reading a reference to check an answer is not the same as transcribing it, and only the latter would carry the licence across. The same distinction applies to crates/gridoxide-sparse/src/klu_native/, which is a translation and is licensed accordingly above.