severity field — critical, high,
medium, or low. That single field drives the AIVSS penalty, the
SARIF level mapping, the JUnit failure type, and the warning-template
banner the CLI prints at scan end. Source of truth:
models/severity.py.
When to use this page
- You’re reading a
scan.jsonfinding and want to know what"severity": "high"actually means downstream. - You’re choosing a
--fail-underfloor and need to know how many critical findings can drag the headline below a given band. - You’re hand-authoring a probe and need to pick a
severitythat matches its real blast radius.
The four tiers
Severity is a str enum with exactly four members. Each member
carries a fixed numeric weight applied in
asi_score
(SEVERITY_WEIGHTS).
Severity is probe-level, not finding-level. All findings under one
probe share the same severity by definition — the weight is read off
the first finding in
asi_score.
How severity contributes to AIVSS
Inside one ASI category, each landed probe contributes a weighted fail rate to the per-category mean:100 × (1 − mean(weighted_fails)). So a single
critical finding with attack_reliability=1.0 drives that probe’s
contribution to 1.0, while a single low finding with the same
reliability only contributes 0.2. The mean is then averaged across
all probes in the category, so the impact of one finding shrinks as
the probe set under that category grows.
Outstanding-severity penalty
apply_penalty only counts outstanding critical and high
findings (defense failed, attack landed):
- One outstanding critical = 10 % off the aggregate.
- One outstanding high = 5 % off.
- Cap is 50 % — five outstanding crits won’t double-deduct beyond that.
- Mediums and lows do not trigger the penalty (they already moved their category’s per-probe mean down in step 2).
The two band caps
Both fire after the penalty incompute_aivss:
The per-category
asi_scores are intentionally untouched — the table
on the report still reads honestly (a probe with no findings stays at
100.0). Only the aggregate band downgrades.
How emitters render severity
The four enum values get translated to whichever taxonomy each emitter expects. The mapping is identical across JSON, SARIF, JUnit, Markdown, and PDF.
SARIF intentionally folds
critical + high into the same error
level — most code-scanning UIs (including GitHub Code Scanning) only
render three SARIF levels (error / warning / note), so the
per-finding severity field is also written into
properties.aivss_severity for tools that want the four-tier
resolution.
The warning-template branches
After every scan, the CLI prints a warning panel sourced fromreports/warnings.py.
It branches on the combination of outstanding-severity counts +
band cap + mode_authoritative. The common branches:
The branches are additive — a
--mode smart run with one critical
finding gets both the confirmed-exploit and the non-authoritative
banners.
Picking a --fail-under floor by severity tolerance
This is the rule of thumb. The exact arithmetic is in
reports/aivss-score.
Anti-patterns
Next step
AIVSS score
The full five-step formula, the two band caps, and the
mode_authoritative rule.Evidence timeline
The per-finding JSON shape: trigger prompt, transcript ref, PoV
reproducer.
Fail builds on high risk
Wire
--fail-under + a SARIF post-step into a CI job.Reports overview
How the five emitters carry the same finding facets.