Expand description
Domain types for fleetreach: the stable, I/O-free contract every other crate maps onto.
fleetreach-core defines the model a fleet scan produces — FleetReport,
VulnFinding, Occurrence, Severity — and their serde shape. It
performs no I/O and exposes no rustsec types, so downstream
enrichment (EPSS, reachability, SARIF) lands as additive fields without
breaking schema_version: 1 consumers. semver values stay typed and
serialize to strings only at the JSON boundary.
§Usage
cargo add fleetreach-coreThe per-occurrence verdict — is the installed version still vulnerable? — is computed against the advisory’s patched range, fail-closed:
use fleetreach_core::semver::{Version, VersionReq};
use fleetreach_core::{DependencyKind, Occurrence, RepoId, Severity};
// Severity is ordered worst-last, so `iter().max()` yields the fleet maximum.
assert!(Severity::Critical > Severity::High);
let occurrence = Occurrence::InRepo {
repo: RepoId("app".into()),
package: "jiff".into(),
installed: Version::new(0, 1, 1),
patched: vec![VersionReq::parse(">=0.1.2").unwrap()],
dependency_kind: DependencyKind::Transitive,
dependency_path: vec![],
active: None,
source: Default::default(),
};
assert!(occurrence.is_vulnerable()); // installed is below the patched range§Minimum supported Rust version
1.89. An MSRV increase is treated as a minor-version bump.
Re-exports§
Modules§
- depgraph
- A name-level dependency graph + shortest introducer-chain BFS, shared by the
toolchain-free feeders to populate
dependency_path(thepkg (via a → b)provenance) without a toolchain. - osv
- OSV advisory version-range matching plus the shared toolchain-free feeder scaffolding
(wire schema, parallel dir/zip loader, by-package index, severity), used by every
ecosystem Tier-C feeder. The per-ecosystem knobs are passed in via
Spec; this matcher is the algorithmic core.
Structs§
- Exploitability
- Exploit-risk enrichment for an advisory, from CISA KEV + FIRST EPSS (added by
--enrich). Additive — its fields are flattened onto the vulnerability and omitted when absent, soschema_version: 1consumers are unaffected. - Fleet
Report - The complete result of one
scan. Field order matches the JSON schema (§9). - Provenance
- Everything needed to reproduce a stored report by re-running with the same
--db-rev. The DB timestamp is the freshness signal (§3). - Reachability
- A static-reachability verdict for a finding’s affected functions, scoped to the toolchain + feature/target config it was computed under (spec §7).
- Remediation
Item - One actionable remediation, derived from one or more
VulnFindings that share a target package. Computed from aFleetReport; never persisted in scan output, so it carries its own ranking signals (max/any across the group) to spare the report layer a re-join. - RepoId
- Stable identifier for a repository, taken verbatim from
fleet.toml— a logical id, never a filesystem path. Paths move; ids are the group key. - Repo
Outcome - Per-repo scan status. A repo we could not read is
Erroredand the run continues — but it forces a non-clean exit (§8): you cannot assert “fleet-clean” over a repo you never read. - Summary
- Vuln
Finding - A vulnerability (a real CVE-class advisory), correlated across the fleet.
- Warn
Finding - A supply-chain warning, correlated across the fleet by
(kind, id).
Enums§
- Action
- What to actually do about a group of advisories on one package.
- DepSource
- Where a vulnerable package resolves from — which registry, git remote, or
local path. This is the identity a VEX subcomponent PURL must carry (spec
§4.1): a crates.io dep is the bare
pkg:cargo/<name>@<ver>PURL, but a git or alternate-registry dep needs a qualifier so a downstream scanner matches the exact artifact. Captured here so the PURL can be derived without re-reading the lockfile. Additive — defaults toCratesIoso a report written before this field existed keeps the crates.io assumption it shipped with. - Dependency
Kind - How a package enters a repo’s dependency graph.
- Ecosystem
- The package ecosystem a finding belongs to: a crate, a Go module, an npm package, a PyPI
distribution, a gem, a Composer package (
Packagist), or aNuGet(.NET) package, so a mixed fleet keeps the namespaces apart (the same name can exist in several). Each is fed by its ownfleetreach-<ecosystem>crate. Ordered so it can key a grouping map. - Occurrence
- A single location/version where an advisory applies.
- Reach
Tier - Where an action sits relative to the active fix queue. Only a sound static
NotReachabledemotes an item to the informational tier — the grep heuristic (VulnFinding::reachable) is too weak to gate, and an absent verdict is treated asUnknown(fail-open: we never hide a vuln on weak evidence, the same stance as--min-epss). - Reach
Verdict - The reachability outcome. The acceptable error direction is over-reporting
(
Reachable/Unknownwhen in fact dead) —NotReachableis sound: there is genuinely no path from a root to the sink under the analyzed config. - Scan
Status - Serializes with a
statustag and the variant fields inlined, e.g.{ "repo": "core-lib", "status": "scanned", "vulns": 2, "warnings": 1 }. - Severity
- Advisory severity, derived from the advisory’s CVSS score (
Unknownwhen the advisory carries no score). - Warn
Kind - The class of a supply-chain warning — informational, not a CVE. Kept in a stream separate from vulnerabilities so warnings never inflate the vuln count.
Constants§
- SCHEMA_
VERSION - Pinned from day one so machine consumers can branch on the wire format. v2 enrichment is additive and must not bump this.
Functions§
- max_
severity_ of - The maximum severity across
vulns(Unknownwhen empty). The single definition of the summary’s “max severity”, so the initial summary and every stage that later filters findings derive it identically. - remediations
- Assemble the remediation queue from a correlated report.