Provenant

Comparison · reproducible

Speed is easy to show. We measured quality too.

A faster scanner is only useful if it's still right. So we ran Provenant and ScanCode on the same well-known repositories and build artifacts, reduced both outputs to their actual findings, and compared them line by line — then annotated every difference that matters.

19.7×
geometric-mean speedup (254 of 254 runs)
9→37×
grows with size (sub-100 → 10k+ files)
70.7×
fastest measured (CPython)
Log-log scatter of scan duration versus file count. Provenant's points sit consistently below ScanCode's across the full range, and the gap widens as file count grows.
Scan duration vs. file count, log-log, on cold license caches — so each run pays a fixed startup cost, which is why both scanners plateau at small file counts. Provenant (lower is faster) stays below the reference across the whole range, and the gap widens with size.
How this was measured. Both scanners run on identical checkouts and artifact snapshots at pinned commits and image digests, with the same scan profile, through Provenant's compare-outputs tool. It reduces each scan to normalized per-file findings, diffs them, and classifies every difference by direction. Speed figures are from docs/BENCHMARKS.md. The quality figures below come from a run on the current stable build at the commit noted, refreshed on each stable release.

curl github.com/curl/curl

The reference and Provenant agree on nearly every license conclusion. Where they diverge on copyright, Provenant is the more faithful of the two — it keeps the “, et al.” that flags additional holders, and preserves non-ASCII names the reference folds away.

4,266
files compared
99.9%
identical license detection (trust baseline)
2,150
files where PV keeps “, et al.” and the reference drops it
verbatim
non-ASCII names & punctuation preserved
Copyright fidelity

Keeps the “, et al.” that flags other holders

ScanCodeCopyright (c) Daniel Stenberg, <daniel@haxx.se>×2,150 files
ProvenantCopyright (c) Daniel Stenberg, <daniel@haxx.se>, et al.×2,150 files
docs/testcurl.md Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
The source ends the notice with “, et al.” — the signal that other copyright holders exist. ScanCode discards it; Provenant keeps it, so the holder line still reads as incomplete rather than pointing at one person.
Copyright fidelity

Preserves non-ASCII names

ScanCodeCopyright (c) Bjorn Stenberg, <bjorn@haxx.se>“Bjorn”
ProvenantCopyright (c) Björn Stenberg, <bjorn@haxx.se>“Björn”
lib/mqtt.c:9 * Copyright (C) Björn Stenberg, <bjorn@haxx.se>
The source spells the author Björn. ScanCode ASCII-folds it to Bjorn; Provenant keeps the name exactly as written — the difference between attributing a person correctly or not.
repo curl/curl @ 2bb5c9b · profile -clupe --system-package --strip-root · reference ScanCode Toolkit · refreshed at each stable release

Redis github.com/redis/redis

The two agree on Redis's licenses overall. Where they differ, it's Provenant reporting the license a file actually carries — and not the ones it doesn't.

1,801
files compared
0
real licenses Provenant fails to report (verified)
bsd-new
vendored jemalloc SFMT sources ScanCode over-tags with AGPL/SSPL
30
files where PV drops an unresolved “unknown license”
Reports the actual license

A BSD file, read as BSD

ScanCodebsd-new AND agpl-3.0 AND mongodb-sspl-1.0 AND rsalv2 AND gpl-1.0-plus AND (agpl-3.0-plus OR apache-2.0) … (12 licenses)SFMT sources
Provenantbsd-newSFMT sources
deps/jemalloc/test/include/test/SFMT.h * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima University. * Redistribution and use in source and binary forms … are permitted provided that * the following conditions are met … [standard 3-clause BSD]
The vendored jemalloc SFMT files are BSD-3-Clause (Saito & Matsumoto, Hiroshima University). ScanCode's expression also pulls in AGPL, SSPL, RSALv2, Apache and GPL — none of which apply; Provenant reports the license the file actually carries.
Drops unresolved noise

No “unknown license reference” cruft

ScanCodeBSD-3-Clause AND LicenseRef-scancode-unknown-license-reference×30 files
ProvenantBSD-3-Clause×30 files
deps/tre/lib/regcomp.c This software is released under a BSD-style license. See the file LICENSE for details and copyright.
The TRE regex files point to a sibling LICENSE file. ScanCode records that pointer as an unresolved unknown-license-reference and ANDs it onto the real license; Provenant resolves the file to BSD-3-Clause and leaves it clean.
No duplicate detections

Says AGPL once, not many times

ScanCodea separate agpl-3.0 detection for every prose mentionREADME, CONTRIBUTING…
Provenantagpl-3.0 once per file (same conclusion)1× / file
README.md … Version 8.0.x and subsequent releases are subject to the tri-license RSALv2/SSPLv1/AGPLv3 at your option as referenced in the LICENSE.txt file.
Redis's docs name the “RSALv2/SSPLv1/AGPLv3” tri-license as prose several times. ScanCode emits a detection for each mention; Provenant reports AGPL once — the file's license conclusion is identical, with less repetition to review.
repo redis/redis @ 5b5c326 · profile -clupe --system-package --strip-root · reference ScanCode Toolkit · refreshed at each stable release

tokio github.com/tokio-rs/tokio

Both scanners find the same packages. Only Provenant knows which of the workspace's crates owns each file.

862
files compared
12
workspace crates resolved (identical both sides)
850
files PV attributes to an owning crate; ScanCode leaves unowned
0
package or dependency identities missed
Monorepo-aware inventory

Which crate owns this file?

ScanCodebenches/copy.rs → (no package owner)unowned
Provenantbenches/copy.rs → pkg:cargo/benchesowned
Cargo.toml (workspace root)[workspace] members = ["tokio", "tokio-util", "tokio-stream", "tokio-macros", "tokio-test", "benches", "examples", "stress-test", …]
tokio is a Cargo workspace of 12 crates sharing one lockfile. Provenant resolves the workspace and attributes each nested source to the crate that owns it (here benches/ → the benches member); across the workspace it attributes 850 files that ScanCode leaves with no package owner — ScanCode links only the 12 manifest files themselves. That file→package graph is what turns a flat list of detections into a per-component inventory — which package each finding actually belongs to.
repo tokio-rs/tokio @ f2189d3 · profile -clupe --system-package --strip-root · reference ScanCode Toolkit · refreshed at each stable release

Amazon Linux 2 container lambci/lambda:provided.al2

Not just source trees — point Provenant at a built container image and it inventories every installed OS package. ScanCode can't open the package database at all.

4,085
files in the image rootfs
45
OS packages inventoried (ScanCode: 0)
590
dependencies recovered (ScanCode: 0)
pkg:rpm/amzn
PURL-correct identities with YumDB provenance
Reads the installed-package database

A full OS inventory where ScanCode sees nothing

ScanCoderpmdb assembly error → 0 packages, 0 dependenciesno inventory
Provenant45 packages, 590 dependencies from the Berkeley rpmdbfull inventory
var/lib/rpm/Packages (binary Berkeley rpmdb)pkg:rpm/amzn/bash@4.2.46-34.amzn2?arch=x86_64 pkg:rpm/amzn/coreutils@8.22-24.amzn2?arch=x86_64 pkg:rpm/amzn/glibc@2.26-39.amzn2?arch=x86_64
The Amazon Linux 2 image records its installed packages in a binary Berkeley rpmdb. ScanCode has no reader for it, reports an assembly error, and leaves the package and dependency inventory empty. Provenant parses the rpmdb into a complete pkg:rpm/amzn/* inventory and merges the YumDB sidecar (repository, checksum, origin, install reason) — the difference between a scannable container and a blind spot.
image lambci/lambda:provided.al2 @ sha256:7765ec11 · profile -clupe --system-package --strip-root · reference ScanCode Toolkit · refreshed at each stable release

The SBOMs behind these scans

Every scan above also produces a full SPDX and CycloneDX SBOM — and every resolved dependency is a real component, not a dangling reference.

100%
of resolved dependencies promoted to real components
0
dangling dependency references, in any format
2
validator-clean formats: SPDX + CycloneDX
4
real projects with full SBOMs checked in
Complete inventory

An SBOM you can actually consume

Provenant promotes every resolved dependency to a component with a versioned package URL and closes the dependency graph — no dependsOn edge points at something the document never lists. A packages-only SBOM names just the top-level project while its relationships still reference materials it never enumerates. The full SPDX + CycloneDX documents for ripgrep, express, flask, and tokio are checked into the repository.

These are four worked examples from a much larger benchmark set spanning source repositories and build artifacts. The full timing table across 254 recorded runs — with every commit and image digest pinned — lives in docs/BENCHMARKS.md, and every comparison here can be reproduced with the compare-outputs tool in the repository.