Skip to main content

Finding Rules

A score alone is useless in an audit; an evidence trail is everything. The primary output of OCSA is therefore a list of findings, each carrying a rule ID, a severity, the evidence (dependency path), the concrete obligation and a recommended action.

Rule catalogue​

RuleSeverityTrigger
LIC-001CRITICALComponent is strong or network copyleft
LIC-003HIGHLicense unresolved — NOASSERTION, empty, or no extracted text
LIC-004CRITICAL / HIGHCustom LicenseRef- text contains copyleft indicators
LIC-005HIGH / MEDIUMIncompatible license pair within one distributed unit
LIC-006CRITICALCopyleft propagates into a distributed unit
LIC-007MEDIUMMulti-licensed (OR) — the election must be documented
LIC-008MEDIUMCopyright text missing or NOASSERTION
LIC-009HIGHLGPL linked without a declared relinking mechanism

LIC-002 is reserved but not implemented — its intended behaviour (weak copyleft static link) is covered by LIC-009. Never renumber existing rule IDs: findings are referenced in reports and in waiver registers.

Propagation rules​

ConditionConsequenceFinding
Strong copyleft + static or undeclared linkage into a distributed unitThe combined work is a derivative workLIC-006 CRITICAL
Strong copyleft + dynamic linkageSeparate work; confirm replaceabilityLIC-006 HIGH (reported)
Weak copyleft (LGPL) + static or undeclared linkageA relinking mechanism is requiredLIC-009 HIGH
Weak copyleft + dynamic linkageNo finding—
Any copyleft ancestorAncestor marked tainted (ring in the graph)—

Why the walk goes upward​

The algorithm walks up from the copyleft component, not down from the root. Only copyleft components initiate a walk, so a BOM with 5 % copyleft performs 5 % of the traversals a root-down search would.

Why taint and findings are decoupled​

Every ancestor is marked tainted, so the graph can draw the ring and the inventory can show inherited risk — but findings are emitted only at the distributed-unit root. The first implementation emitted a finding per hop and produced 22 identical CRITICAL entries for a single AGPL component. That is BUG-06. No information is lost: the taint chain is still visible in the detail panel, but the findings list stays actionable.

Cycle safety​

Hand-maintained SBOMs regularly contain A DEPENDS_ON B and B DEPENDS_ON A. The BFS tracks best-known hop distance per node and refuses to revisit, so the walk terminates.

Structure of a finding​

{
id: 'F-042',
rule: 'LIC-006',
severity: 'CRITICAL',
title: 'Strong copyleft from "busybox" propagates into "IVI-HMI-Application"',
component: 'IVI-HMI-Application',
componentId: 'SPDXRef-Pkg-IVI-HMI-Application',
detail: 'busybox (GPL-2.0-only) → IVI-HMI-Application, linkage not declared',
obligation: 'Provide complete corresponding source of the derivative work under the same license',
action: 'Confirm linkage with the supplier; if static, either replace the component or plan source disclosure'
}

Finding is immutable and self-contained: every field needed to act on it is in the finding itself. That is what makes findings the unit of export, of diffing, and — in Phase 2 — of waiver.

The title names the source component. The first implementation used identical titles for all LIC-006 findings, which made the list unusable; that was BUG-17.

Release gate criteria​

A distributed unit passes when all of the following hold:

  • Zero CRITICAL findings (unless an approved waiver exists — Phase 2)
  • HIGH findings within the configured threshold
  • Zero unresolved licenses
  • SBOM quality at or above the configured minimum

Worked example​

On the bundled 4.2.0 demo SBOM (42 components, 45 relationships):

Risk score: 61 (HIGH) SBOM quality: 50%
Findings: CRITICAL=13 HIGH=30 MEDIUM=8 (51 total)

Top findings:
[CRITICAL] LIC-006 Strong copyleft from "busybox" propagates into "IVI-HMI-Application"
[CRITICAL] LIC-006 Strong copyleft from "linux-kernel" propagates into "IVI-HMI-Application"
[CRITICAL] LIC-006 Strong copyleft from "eclipse-mosquitto-client" propagates into "IVI-HMI-Application"
[CRITICAL] LIC-004 Custom license text on vendor-camera-sdk shows copyleft indicators
[CRITICAL] LIC-001 Strong copyleft component: busybox

The fixture was authored to contain exactly the failure modes that matter: an AGPL component statically linked into a proprietary telematics agent, LGPL components statically linked without declared relinking, a NOASSERTION component, a custom LicenseRef- whose extracted text mentions the GPL, and CDDL/EPL components that conflict with GPL in the same subtree.