Approval Layers

ReuseLicensing separates license approval into layers. The lowest layer works only on SPDX license expressions. Later layers will build on that result when checking file metadata and complete repositories.

Expression-Level Approval

Expression-level approval answers one narrow question: does an SPDX license expression contain at least one licensing path accepted by a policy?

This layer is deliberately agnostic about files, file contents, copyright statements, license text placement, and repository layout. It only evaluates the normalized SPDX expression tree returned by parse_spdx_expression.

Approval Policies

Approval is policy-dependent. ReuseLicensing currently provides policies based on the checked-in SPDX License List snapshot:

  • OSIApproved: accepts SPDX license identifiers marked as OSI approved.
  • FSFLibre: accepts SPDX license identifiers marked as FSF libre.
  • UnconjoinedOSIApproval: accepts OSI-approved package license expressions without conjunctions.
  • OpenContentApproval: accepts selected non-code content licenses, currently CC0-1.0, CC-BY-4.0, and CC-BY-SA-4.0.

Policies can be combined:

  • AnyOf: accepts a simple license expression when at least one nested policy accepts it.
  • AllOf: accepts a simple license expression only when every nested policy accepts it.

Approved License Paths

The main predicate is has_approved_license_path. For composite SPDX expressions it follows the structure of the expression:

  • A OR B: approved if either branch has an approved path (disjunction).
  • A AND B: approved if both branches are approved (conjunction).
  • LicenseRef-*: not approved by policies based on SPDX License List data.
  • A WITH exception: currently treated conservatively as not approved.

The name "license path" is intentional. For an OR expression, an expression can be approved even when one branch is not accepted, as long as another branch provides an accepted path.

Stricter Approval Policies

UnconjoinedOSIApproval and OpenContentApproval currently do not approve conjunctions of license identifiers. This is a stricter rule than the generic expression-level semantics used by policies such as OSIApproved and FSFLibre, where an AND expression is approved when all branches are approved.

Examples

An expression with two OSI-approved licenses is accepted:

using ReuseLicensing

has_approved_license_path("MIT OR Apache-2.0", OSIApproved())
true

The generic OSIApproved policy also accepts a conjunction when all branches are OSI-approved:

has_approved_license_path("MIT AND Apache-2.0", OSIApproved())
true

The stricter UnconjoinedOSIApproval policy does not approve such conjunctions as package-level code license expressions:

has_approved_license_path("MIT AND Apache-2.0", UnconjoinedOSIApproval())
false

For OR, one accepted branch is enough:

has_approved_license_path("MIT OR LicenseRef-Internal", OSIApproved())
true

Under the generic expression-level semantics, an AND expression is rejected if one branch is not approved:

has_approved_license_path("MIT AND LicenseRef-Internal", OSIApproved())
false

Policies can be composed when a project accepts more than one approval source:

policy = AnyOf(OSIApproved(), FSFLibre())

has_approved_license_path("CC0-1.0 OR 0BSD", policy)
true

WITH expressions are parsed, but approval is intentionally conservative for now:

has_approved_license_path(
    "GPL-2.0-only WITH Classpath-exception-2.0",
    OSIApproved(),
)
false

Use ValidSPDX to accept any valid SPDX license expression without applying an additional approval policy:

has_approved_license_path("MIT AND LicenseRef-Internal", ValidSPDX())
true

API Reference

ReuseLicensing.has_approved_license_path — Function
has_approved_license_path(expr, policy; legacy = :normalize)
has_approved_license_path(parsed::ParsedSPDXExpression, policy)

Return whether an SPDX license expression has at least one license path approved by policy.

String inputs are parsed with parse_spdx_expression. OR expressions require one approved branch; AND expressions require all branches. WITH expressions are currently treated conservatively as not approved by restrictive policies.

source
ReuseLicensing.OSIApproved — Type
OSIApproved()

Approval policy that accepts SPDX license identifiers marked as OSI approved in the checked-in SPDX snapshot.

source
ReuseLicensing.FSFLibre — Type
FSFLibre()

Approval policy that accepts SPDX license identifiers marked as FSF libre in the checked-in SPDX snapshot.

source
ReuseLicensing.UnconjoinedOSIApproval — Type
UnconjoinedOSIApproval()

Approval policy for OSI-approved license paths without conjunctions.

This policy is useful when an expression is expected to provide at least one clear OSI-approved license path, rather than a conjunctive set of simultaneously applicable license obligations.

The policy accepts single OSI-approved SPDX license identifiers and OR expressions with at least one acceptable OSI-approved branch. It deliberately does not approve conjunctive AND expressions, even if all conjuncts are individually OSI-approved. Such expressions may be valid SPDX expressions for file sets or combined distributions, but they are not accepted by this stricter path-oriented policy.

source
ReuseLicensing.OpenContentApproval — Type
OpenContentApproval()

Approval policy for selected open-content and public-domain-style licenses.

This policy is useful for documentation, examples, metadata, configuration files, assets, and other non-code material in REUSE/SPDX-aware repositories. It is intended as a reusable content-licensing building block and can be combined with software license policies such as UnconjoinedOSIApproval where a broader file-level approval rule is needed.

The policy accepts selected open-content and public-domain-style licenses such as CC0-1.0, CC-BY-4.0, and CC-BY-SA-4.0. These licenses are accepted by major free/open-source policy references, including the FSF, Debian, Fedora, and the Eclipse Foundation:

The accepted set is intentionally narrow and does not include non-commercial or no-derivatives Creative Commons variants.

source
ReuseLicensing.AnyOf — Type
AnyOf(policies...)

Approval policy combinator requiring at least one nested policy to approve a simple SPDX license expression.

source
ReuseLicensing.AllOf — Type
AllOf(policies...)

Approval policy combinator requiring every nested policy to approve a simple SPDX license expression.

source
ReuseLicensing.ValidSPDX — Type
ValidSPDX()

Null-level approval policy that accepts any valid SPDX license expression.

This policy checks only SPDX syntax and identifier validity. It does not make a legal, compatibility, Free Software, Open Source, registry, or project-specific approval judgment.

source

File-Level Approval

File-level approval is planned as a separate layer. It will build on expression-level approval and add file-level licensing concerns such as discovered SPDX license expressions, where they were found, and file-specific issues.

Repository-Level Approval

Repository-level approval is planned as an aggregation layer over file-level results and repository checks such as REUSE lint output and required license texts. It is distinct from package-level licensing, which records and validates the outbound package-level declaration in Project.toml and LICENSE.