Reviewer quick-reference card
One page, for printing. Every table below is generated from the constants the engine enforces, so this card cannot drift from the tool. The full walkthrough is the reviewer runbook.
Important
SBOMFlow observed; you decide. No status the engine writes is a review
decision, and under_investigation means nobody has decided yet — never
this is fine.
Review states (workflow only)#
| State | What it means |
|---|---|
open | Nobody has picked this up. Not a judgement about the item. |
in_review | Someone claimed it with review --start. Coordination only — no evidence authority. |
decided | A decision was recorded. The decision, not the state, is what counts. |
A claim (review --start <key> --as ROLE) can target evidence (an observed evidence signal), vulnerability (an advisory finding), gap (a requirement with no evidence at all).
Evidence decisions (reviews.json)#
| Decision | When to use it |
|---|---|
accepted | You looked at it and it really is evidence. Cite what convinced you with --evidence-ref. |
rejected | The observed signal is not evidence for this requirement (stale config, wrong file). |
needs_more_evidence | Not a no. Say precisely what is missing in --note. |
Finding triage — VEX status (vulnerability_reviews.json)#
| Status | What it asserts |
|---|---|
not_affected | A claim about your product. Requires a CISA justification — the CLI refuses without one. |
affected | The product is affected. Fix it, or waive it with a reason and an expiry. |
fixed | Already remediated in this release. Say where. |
under_investigation | The engine's default. It means nobody has decided yet — never 'this is fine'. |
The five CISA justifications for not_affected#
| Justification | Claim you are making |
|---|---|
component_not_present | The affected component does not ship in this product. |
vulnerable_code_not_present | The component ships, but the vulnerable code does not. |
vulnerable_code_not_in_execute_path | The vulnerable code ships but can never be reached. |
vulnerable_code_cannot_be_controlled_by_adversary | Reachable, but an attacker cannot influence the inputs. |
inline_mitigations_already_exist | A compensating control in the product prevents exploitation. |
A category alone is not an explanation. sbomflow review <output> --template <justification> prints the scaffold of what a reader needs.
Why a release gate blocked#
| Reason code | Meaning |
|---|---|
GATE_ADVISORY_FINDINGS | Unresolved advisory findings at/above the severity threshold |
GATE_AI_CONTROL_UNEVALUATED | An enforced AI control could not be evaluated |
GATE_AI_DECLARED_FACT_CHANGED | Material declared AI fact(s) changed since the previous release |
GATE_AI_DRIFT_UNCOMPARABLE | AI evidence was never compared against the previous release |
GATE_AI_EVIDENCE_CONFLICT | Observed and declared AI facts disagree and are unresolved |
GATE_AI_INVENTORY_PARTIAL | The AI inventory is partial — a traversal budget cut the walk short |
GATE_AI_MODEL_CHANGED | Model artifact(s) do not hold the same bytes as the previous release |
GATE_AI_UNSUPPORTED_FORMAT | Model artifact(s) were recorded but deliberately never parsed |
GATE_APPROVAL_BINDING_MISMATCH | Release approval(s) were granted against different evidence or a different gate policy |
GATE_DATA_UNAVAILABLE | An enforced policy required data this run never loaded |
GATE_DENIED_LICENSE | Component(s) declare a license on the operator deny list |
GATE_DRIFT_UNAVAILABLE | A drift policy was enforced with no previous release to compare |
GATE_EPSS_THRESHOLD | Finding(s) at/above the configured FIRST EPSS threshold |
GATE_EPSS_UNINTERPRETABLE | Finding(s) carry an EPSS score with no model/score date |
GATE_EVIDENCE_GAPS | Missing-evidence gaps at/above the severity threshold |
GATE_EVIDENCE_REGRESSION | Previously-accepted evidence regressed |
GATE_KEV_PRESENT | Finding(s) in the CISA KEV catalog (known exploited) |
GATE_MISSING_APPROVALS | Required multi-role release approvals are incomplete |
GATE_NEW_ADVISORY_FINDINGS | New advisory finding(s) vs the previous release |
GATE_NEW_CRITICAL_OR_HIGH | New or escalated critical/high finding(s) vs the previous release |
GATE_NEW_KEV | Newly known-exploited finding(s) vs the previous release |
GATE_NEW_REACHABLE_FINDINGS | Finding(s) that became source-referenced in this release |
GATE_REACHABLE_FINDINGS | Source-referenced (reachable) advisory finding(s) |
GATE_SEVERITY_UNDETERMINED | Item(s) have no determinable severity to compare against the threshold |
GATE_STALE_ACCEPTED_EVIDENCE | Accepted evidence item(s) past their own recorded validity window |
GATE_STALE_VULNERABILITY_DATA | Consulted vulnerability source(s) exceed the operator freshness SLA |
GATE_SUPPORT_PERIOD_MISSING | Current release does not declare a support period |
GATE_UNATTRIBUTED_EVIDENCE | Evidence decision(s) recorded with no named reviewer |
GATE_UNREVIEWED_EVIDENCE | Observed evidence items not yet human-reviewed |
Run sbomflow explain <output> --gate to see which of these fired.
The five commands#
# See what needs a decision
sbomflow review ./evidence
# Understand one item first
sbomflow explain ./evidence --gate
# Record an evidence decision
sbomflow review ./evidence --accept secure_boot_configured --reviewer you@example.com
# Sign off your role
sbomflow approve ./evidence --role product-security --reviewer alice@example.com --author bob@example.com
# Hand it to the auditor
sbomflow bundle ./evidenceEscalation#
If a finding is genuinely exploitable in your product and cannot be fixed before release, that is an escalation to your release owner. It is not a status you can pick in this tool, and no flag makes it go away.
SBOMFlow never sets a VEX status for you, never treats an observed signal as accepted evidence, never files or signs a regulatory report, and never says you are compliant.