Every component carries a confidence: an evidence-weighted score in [0,1] that the component is really there and really identified as claimed.
Weighted, not calibrated. Per-sighting scores are assigned by rule and detector authors from how distinctive the evidence is, then combined as described below. The result is ordinal: a 0.9 rests on stronger evidence than a 0.6. It is not a calibrated probability: no study yet establishes that findings scored 0.85 are correct 85% of the time. Read the number as evidence strength, and treat any tool that claims statistical calibration without a published benchmark with suspicion, this one included.
Two rules govern it:
  1. Detectors never set component confidence. A detector scores its own sighting. The engine assembles the component-level number from every sighting.
  2. Filtering is presentation, never assembly. --min-confidence trims what you see. It never changes what was merged, what evidence was recorded, or what any component scored.

How the engine assembles it

Confidence is a grouped noisy-OR over the occurrences behind a component. Three steps:
1

Group per detector and method

For each (detector, method) pair, take its highest sighting confidence, then add a small bonus for repeat sightings by that same pair:
The bonus is capped at 0.15. Seeing the same thing twenty times with one detector is only marginally better evidence than seeing it twice, because the sightings are not independent.
2

Noisy-OR across methods

Reduce the groups to a per-method maximum, then combine across methods:
This is where confidence really rises. Independent methods reinforce each other: a model named in a lockfile and fingerprinted in an AST and matched by a file header is strong evidence in a way that three source-code regex hits are not.
3

Clamp at 0.99

The result is capped at 0.99, unless the evidence includes a hash-comparison sighting (or, in v2, a verified attestation).
The 0.99 clamp is a statement of epistemics, not a fudge factor. Static analysis reads what the code says, not what it does. Only a digest matched against known weights lets AIROM assert certainty, which is the one v1 path to 1.0.
The multiplication runs in sorted method order deliberately. Float multiplication is not associative, so map-iteration order would make the last bits of the score vary between runs. AIROM’s output is reproducible.

Bands

The SDK type airom.Confidence offers a Band() helper that buckets a score into three names:
Bands are a convenience for consumers of the Go SDK. No AIROM output emits them: they are not stored, not a field in any format, not shown in the table (which prints the float, 0.87), and not usable in a --fail-on expression. The float is the real value, so compare against it, not against a band name.

Filtering with --min-confidence

--min-confidence takes a float in [0,1] and drops components scoring below it.
High-signal view
What it does:
  • Keeps every component at or above the threshold.
  • Always keeps the application root, so the output still identifies what was scanned.
  • Drops relationships whose endpoints did not both survive, so there are no dangling edges.
  • Leaves assembly untouched. Re-run without the flag and everything is back.
--min-confidence is a per-run setting, not a per-output one. It applies to every output of that run, so a -o table -o json=airom.json run writes the same filtered set to both. If you want a quiet table and a complete archival document, run the export a second time without the flag.

Be honest about the noise

On general-purpose directories, AIROM’s default output contains low-confidence noise. This is a real limitation, not a tuning preference.
Two detection paths are responsible: These sightings are honest about themselves: they carry the filename and config-analysis methods, and they score accordingly. AIROM reports them rather than hiding them, because a silently dropped dataset is worse than a noisy one. But on a repo that is not AI-focused, they will dominate the component count. The practical filter is --min-confidence 0.8. It clears both classes while keeping anything corroborated by an independent method, such as a .parquet file confirmed by its magic bytes scores 0.8 on binary analysis alone and survives; a .csv matched only by its extension does not.
Recommended for a first look at an unfamiliar repo
If you want a stricter view still, narrow what runs rather than what prints. --select takes an include/exclude expression whose tokens are detector IDs, so you can drop the dataset detector outright:
Scan without the dataset detector
Selection is per detector, not per rule pack. The low-confidence ai-config rules live inside the ruleengine detector alongside every other rule, so there is no --select token that drops just those. --min-confidence is the tool for that class of noise.
Every token must match a registered detector ID or tag, or the run fails with a usage error rather than silently doing nothing. Check a selection before you scan:
Check what a selection actually enables

Confidence in CI

--fail-on compares against the assembled float directly:
Fail only on high-confidence hosted model references
--min-confidence and --fail-on are fully independent. --min-confidence shapes the document; --fail-on decides the exit status, and it evaluates against the complete, unfiltered inventory. Raising --min-confidence to quiet the table will not weaken your CI gate. Put the confidence threshold in the --fail-on expression itself if that is what you want to gate on.

Evidence model

The occurrences and methods that feed the score.

What is an AIBOM

The 13 component kinds.