Skip to main content

License Tiers

Every license is classified into one of five tiers. This table is the heart of the tool — it is the artefact legal counsel is asked to ratify in milestone M-8.

The tier model​

TierRankCategoriesMeaning
CRITICAL5strong-copyleft, network-copyleftDistribution triggers source disclosure of the derivative work
HIGH4weak-copyleft, file-copyleftObligations attach to the library or to modified files
UNKNOWN3.5unknown, custom-ref, unrecognised, proprietaryRelease blocker until triaged
MEDIUM3conditional, non-commercial, no-derivatives, share-alike, ambiguousRequires review
LOW2permissive, public-domainNotice and attribution only

Ranks are deliberately non-contiguous and unique. UNKNOWN sits at 3.5 — a fractional rank between MEDIUM and HIGH — so that a rank lookup can never match two tiers. This was BUG-01: with HIGH and UNKNOWN both at rank 4, a lookup by rank returned HIGH for an UNKNOWN license.

Because AND takes the worst case, GPL-2.0 AND NOASSERTION still resolves to CRITICAL (5 beats 3.5) — the copyleft is not masked by the unresolved term.

The obligation catalogue​

Obligations are what compliance work actually produces. Each license rule maps to a set of them:

ObligationWhat it requires
noticeInclude the copyright notice and a copy of the license text in the distribution
state-changesState that the component was modified, and the date of modification
source-fullProvide complete corresponding source of the derivative work under the same license
source-modifiedProvide source of any modifications made to the licensed component
relinkingProvide object files, or a mechanism letting the recipient relink against a modified library
network-sourceOffer source to users who interact with the software over a network
install-infoProvide installation information (keys, credentials) so modified firmware can be installed — GPL-3 anti-tivoization
patentInclude the patent grant and patent-termination notice
no-endorsementDo not use contributor or organisation names for endorsement
advertisingInclude an acknowledgement in advertising materials
non-commercialNon-commercial use only — not approved for commercial distribution

install-info is worth noting: GPL-3 adds anti-tivoization terms, which are directly relevant to signed ECU firmware. Whether they bite depends on facts a tool cannot see, which is one reason the output is triage.

Rule matching​

Rules live in LICENSE_RULES and are matched longest-prefix, case-insensitively:

{ match: 'lgpl-2.', tier: 'HIGH', cat: 'weak-copyleft',
obl: ['notice', 'state-changes', 'source-modified', 'relinking'],
note: 'In automotive monolithic firmware, LGPL static linking is the most common compliance gap.' }

match: 'lgpl-2.' covers LGPL-2.0-only, LGPL-2.1-or-later and LGPL-2.1+ in one entry. Because the whole knowledge base is declarative data, adding a license is a one-line change.

SPDX expression evaluation​

The grammar is a small recursive-descent parser:

expr := term (OR term)*
term := factor (AND factor)*
factor := '(' expr ')' | id ('+' | WITH id)?

AND takes the worst case, OR the best​

This is not a simplification — it reflects what the operators mean. A AND B means both licenses apply simultaneously, so the strongest obligation governs. A OR B grants a choice, so the licensee may elect the more favourable term.

Scoring OR as the worst case would systematically over-report dual-licensed components (Qt, ffmpeg, NSS…), which is precisely the kind of false positive that gets a compliance tool ignored. But the election must be recorded, because it determines the obligation actually owed — hence the LIC-007 note.

Linking exceptions​

GPL-2.0-or-later WITH u-boot-exception-2.0 is not the same risk as GPL-2.0-only. Ignoring exceptions floods the report with false positives and destroys credibility with suppliers — the fastest way to get a tool ignored.

ExceptionRelaxesNote
classpath-exception-2.0yesLinking does not impose GPL on the application
u-boot-exception-2.0yesStatic linking of GPL-2.0+ U-Boot into firmware is permitted
gcc-exception-3.1, gcc-exception-2.0yesGCC runtime library exception
autoconf-exception-2.0, autoconf-exception-3.0yesAutoconf configure-output exception
bison-exception-2.2yesBison parser-skeleton exception
font-exception-2.0yesDocuments using the font are not covered
llvm-exceptionyesRelinking against modified LLVM is preserved
qt-gpl-exception-1.0yesQt GPL exception
swift-exception, libtool-exceptionyes—
linux-syscall-notenoUser-space programs calling the kernel are not derivative works — but the tier is unchanged

Note the last row: an exception with no relaxation effect must not downgrade. That is TC-04, and getting it wrong in the other direction would silently under-report.

The relaxation ladder deliberately excludes UNKNOWN. When a GPL license carries a linking exception, the tier steps down within the copyleft strength scale (CRITICAL → HIGH). If UNKNOWN were on the ladder, CRITICAL would relax onto UNKNOWN and produce a nonsense verdict that looks like missing data. This was BUG-02.

Compatibility conflicts​

Known incompatibilities are a coarse table matched on license family prefixes, because the well-known conflicts are family-level properties. Each rule carries a rationale that is surfaced verbatim in the finding, so a reviewer sees why two licenses conflict.

PairSeverityRationale
gpl-2.0 + apache-2.0HIGHApache-2.0 patent/indemnity terms are additional restrictions under GPL-2.0
gpl-2.0 + gpl-3.0HIGHGPL-2.0-only and GPL-3.0 are mutually incompatible
gpl-2.0 + lgpl-3.0HIGHLGPL-3.0 requires GPL-3.0, which is incompatible with GPL-2.0-only
gpl-2.0 + epl-HIGHEPL and GPL are mutually incompatible
gpl-2.0 + cddl-HIGHCDDL and GPL are mutually incompatible
gpl-2.0 + mpl-MEDIUMMPL-2.0 offers GPL-2.0 as a secondary license, but combination still needs review
agpl- + gpl-2.0HIGHAGPL-3.0 and GPL-2.0-only are mutually incompatible
agpl- + apache-2.0MEDIUMGenerally compatible, but the combined work becomes AGPL
epl- + cddl-MEDIUMBoth file-level copyleft, but not cross-compatible
cc-by-nc- + apache-2.0 / mitHIGHNon-commercial terms cannot be combined with commercial licenses
cc-by-sa- + apache-2.0MEDIUMShare-alike propagates to the combined work

:::caution Granularity is the known weakness Conflicts are computed over the transitive subtree of a root, so two components in separate executables that happen to share a root would be reported as conflicting even though they never combine. Resolving this needs a process/executable boundary map from the supplier (P2-06). Until then the behaviour is conservative and documented. :::