Skip to content

Conversation

@zvr
Copy link
Member

@zvr zvr commented Aug 19, 2025

This updates the annex on SPDX License Expressions.

It adds "NONE" and "NOASSERTION" that can be used on their own or in AND expressions.

Some additional minor changes:

  • it makes it explicit that AdditionRef and DocumentRef are to be treated like LicenseRef
  • it cleans up wording in a couple of places
  • It removes references to "tag: value" format
  • It removes obsolete RDF section

It also adds, at the end of the annex, a complete grammar that accurately describes the expressions. The general grammar in the beginning only gives hints about the general format, but one has to rely on text explanations and clarifications in order to actually correctly use expressions.

Closes #49
Closes #50

Signed-off-by: Alexios Zavras (zvr) [email protected]

@zvr zvr added this to the 3.0.2 milestone Aug 19, 2025
@zvr zvr requested review from bact and goneall August 19, 2025 09:08
addition-ref = [%s"DocumentRef-"(idstring)":"]%s"AdditionRef-"(idstring)
simple-expression = license-id / license-id"+" / license-ref
simple-expression = license-id / license-id"+" / license-ref / "NONE" / "NOASSERTION"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding (and please correct me if I'm wrong!) is that @JPEWdev's original suggestion was to add "NONE" and "NOASSERTION" as actual license identifiers to the license list (including all associated metadata for them). If that's the solution, then adding NONE and NOASSERTION as "special cased" simple-expression values is redundant - they'd be covered automatically as any other license-id.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what the "original suggestion" was, but I have never heard of adding "NONE" and "NOASSERTION" to the SPDX License List.
I am opposed to this (as they are not licenses), and I am pretty confident the Legal Team will also disagree. Such an addition would also require changes to the model, deletion of the corresponding Individuals, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC it was more of a suggestion than anything. The annoyance with them not being actual "real" licenses is that all code will need to have special cases to deal with them. It's not impossible, just annoying

Copy link

@pmonks pmonks Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to what @JPEWdev said - not having these in the license list is more of an irritation than a showstopper. But that said, without additional machine-readable metadata (somewhere) these values appearing in an SPDX license expression will be difficult for a reader unfamiliar with SPDX to interpret, given that each tool will likely present this information in different and somewhat arbitrary ways. Given that in large (transitive) SBOMs these values will be almost ubiquitous, it seems unwise to me to special case / hard code them as is implemented here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had some discussion on this during a code review of a Java library:

(click to "show resolved" there to see more of @pmonks and my comments)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In license expressions serialized as strings, they are two special identifiers, as they have been for around 15 years.
In actual linked data, they are definitely defined as individual elements: NONE and NOASSERTION.

Copy link

@pmonks pmonks Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zvr until recently NONE and NOASSERTION were not part of the SPDX *license expression specification, notwithstanding their use by certain tooling. I think it's a mistake to blindly adopt the semantics that those tools chose, without thinking more broadly about how it should be implemented in a formal manner.

Furthermore, independent license expressions serialised as strings without any supporting model is a common occurrence, especially in ecosystems (such as the Java / Maven ecosystem, one of the largest extant package ecosystems) that don't support SPDX directly. To me, supporting SPDX tool developers who operate in those ecosystems has merit, whatever one might think of those ecosystems and their lack of direct SPDX support.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, NONE and NOASSERTION have been present as SPDX licensing values since the original v1.0 was released in 2010/2011. See https://spdx.dev/wp-content/uploads/sites/31/2023/09/spdx-1.0.pdf, section 4.12 for example.


```text
MIT AND (LGPL-2.1-or-later OR BSD-3-Clause)
(LGPL-2.1-or-later OR BSD-3-Clause) AND MIT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(LGPL-2.1-or-later OR BSD-3-Clause) AND MIT
MIT AND (LGPL-2.1-or-later OR BSD-3-Clause)

I think the original author of this example purposefully put AND at the front, before OR, to demonstrate that the parentheses can be used to let OR applied before - despite its location at the back. So I suggest we keep the original example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this reorders the terms from the previous example. The idea was to show and explain the expression without parentheses and then say "if you want to do the other way, add parentheses".

```

It is allowed to use the operator in lower case form `or`.
The special identifiers "NONE" or "NOASSERTION" cannot be used with the OR operator.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the "OR" at lines 94 and 102 as well. It should be OR, the same format as other instances.

Copy link
Member

@goneall goneall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple suggested / questions

@pmonks
Copy link

pmonks commented Aug 22, 2025

I just want to clearly reiterate that I think this particular solution for implementing NONE and NOASSERTION sets a bad precedent. What happens when other "special case" pseudo-identifiers (such as PROPRIETARY) are introduced to the specification?

I firmly believe these values are better modeled as data (e.g. in the license list, with appropriate metadata) rather than hardcoded into the grammar as an ever-increasing set of special cases.

@zvr
Copy link
Member Author

zvr commented Aug 26, 2025

@bact do you feel strongly about changing all instances of words like "AND" to AND?
I feel that all the formatting changes (font changes in PDF) will be distracting and confusing at the end, so I'd rather just have them as words-in-quotes -- and use the other construct for example expressions.

In any case, we should be consistent throughout the annex (at least).
Let me know and I'll push a relevant commit.

@bact
Copy link
Collaborator

bact commented Aug 26, 2025

Can choose any style but should be consistent. AND, OR, and WITH should look the same. Currently they are not.

@zvr
Copy link
Member Author

zvr commented Aug 26, 2025

Discussed on 2025-08-26 Tech call

  • should use "THIS" format consistently to refer to operators and special identifiers
  • addition of special identifiers to the SPDX License List can be done at a later stage, after agreement of Legal Team

I will be pushing a commit tomorrow implementing this (and fixing the typos raised)

@pmonks
Copy link

pmonks commented Aug 27, 2025

addition of special identifiers to the SPDX License List can be done at a later stage, after agreement of Legal Team

@zvr if this happens will the hardcoded values NONE and NOASSERTION be removed from the grammar, given that they would then conflict with values in the license-id and license-exception-id production rules?

@zvr
Copy link
Member Author

zvr commented Aug 27, 2025

@pmonks If they are ever added to the License List, we will have to change a number of things: the model, some definition wordings, and obviously the grammar here. For example, we still have to be able to express that these specific entries from the License List cannot be used with "OR", "WITH" or "+".

@pmonks
Copy link

pmonks commented Aug 27, 2025

@zvr the restriction on using these constructs with AND only isn't codified in the grammar, so I'm less concerned about that.

And again, I'm concerned that this particular implementation choice is going to result in ongoing churning of the grammar - either an ever-growing set of special case values, or flip-flopping back and forth between different methods for representing them.

I'm sorry I wasn't able to join this week's calls to discuss my concerns in person - as @goneall is aware I have ongoing medical appointments that conflict every few weeks with the SPDX call schedule, and by unfortunate coincidence this was one of those weeks. I would appreciate the opportunity to ensure that my concerns are understood and that we don't just rush to a solution that is not future-proof.

@goneall
Copy link
Member

goneall commented Aug 27, 2025

@pmonks - I'm not as concerned about the grammar churn - many (but not all) of the parsers I've run across (and I've run across quite a few) have allowed NONE and NOASSERTION already. In the past, the legal team has pushed back on adding anything to the license list that isn't represented by well defined license texts. For example, the concept of adding a "proprietary" or "commercial" generic license has been rejected by the legal team more than once.

In the world of RDF, the URI's used to represent NONE and NOASSERTION are defined in the spec (not the license list) and they have already been established with a prefix containing spdx.org/rdf/terms which is different for the URI's for the license list which has a prefix containing spdx.org/licenses. Hence the strong resistance to changing NONE and NOASSERTION from being defined in the spec to being defined in the license list.

What we decided on the call was to postpone this particular decision and go with the more compatible grammar updates.

If we did want to move NONE and NOASSERTION from the spec to the license list, it would likely be in 4.0 since I think it would be a breaking change for the RDF users.

@pmonks
Copy link

pmonks commented Aug 27, 2025

@goneall so what happens when other "special terms" (e.g. PROPRIETARY seems likely, and IME PUBLIC_DOMAIN may be required eventually too) are added to the spec? Does the grammar just grow into a long list of special terms?

I feel pretty strongly that this is, at core, a data representation question, and that hardcoding data in the grammar (which is effectively code) is a fairly profound mistake.

@goneall
Copy link
Member

goneall commented Aug 27, 2025

so what happens when other "special terms" (e.g. PROPRIETARY seems likely, and IME PUBLIC_DOMAIN may be required eventually too) are added to the spec? Does the grammar just grow into a long list of special terms?

I agree we don't want to continually update the grammar if these additional terms get added.

The proposal to add these to the license list, I'm pretty sure won't fly with the legal team since it's been proposed and rejected more than once before. Adding NONE and NOASSERTION to the license list would also break compatibility for RDF users which I (and other RDF users) would object to.

We may be able to come up with a solution where a simple license expression could be:

  1. a listed license
  2. a licenseRef
  3. another list of terms representing some semantic information not represented by license text (a.k.a special terms, e.g. NONE, NOASSERTION, PROPRIETARY, etc.)

This could solve your issue that we don't have to churn the grammar when adding these "special terms".

We currently don't have 3 defined, but we could add it later and replace NONE and NOASSERTION with a reference to an externally maintained list. For tooling, we'd need to put in place some kind of infrastructure like the license list so these terms could be referenced - a bit of work, but not out of the question.

I think this could be done in the future since it wouldn't be a breaking change as long as the URI prefixes for NONE and NOASSERTION are unchanged.

I suggest we go with the current proposed changes to the Annex and continue the discussion on adding other terms with the legal team.

@zvr
Copy link
Member Author

zvr commented Aug 27, 2025

@pmonks I understand your point, but I don't agree with "ever-growing set of special case values" that you fear.

"NONE" and "NOASSERTION" are the only special values and they have been there since almost the beginning (more than 12 years).

@pmonks
Copy link

pmonks commented Aug 27, 2025

@zvr these values have never been in the official SPDX expression grammar, and there are alternative approaches for supporting them in expressions that are more future proof than hardcodng them into the grammar, that I don't think have been adequately considered.

@pmonks
Copy link

pmonks commented Aug 27, 2025

@goneall yet the legal team have previously approved adding NONE and NOASSERTION elsewhere in the spec (and are currently discussing adding PROPRIETARY too), so if there are solid technical reasons to add these values as "special cases" to the license list, I have to assume that they would at minimum (re)consider the idea.

And if they don't, then perhaps a separate "technical license-esque list" should be maintained as data on the technical side - that too would address my concerns about hardcoding "magic values" in code.

@zvr
Copy link
Member Author

zvr commented Aug 28, 2025

Merging this now, to produce 3.0 version and the discussion for further changes can continue separately.

@zvr zvr merged commit f65ec26 into spdx:support/3.0 Aug 28, 2025
3 checks passed
@zvr zvr deleted the update-licexpr-annex branch August 28, 2025 10:13
@goneall
Copy link
Member

goneall commented Aug 28, 2025

@pmonks - A good topic for the legal team - I not current on the discussion, so there may have been some change in the tides around this topic I'm not aware of. As you mentioned, it has always been part of the spec, but it was documented as the range of property values in the SPDX spec - not in the license list itself (e.g. you won't find an entry at https://spdx.org/licenses/).

The only technical requirement I have is we don't change the RDF URI from https://spdx.org/rdf/3.0./terms/Licensing/None or NoAssertion to https://spdx.org/licenses/None or NoAssertion.

cc: @swinslow @jlovejoy - discussion on how to handle the "special" license types such as NONE and NOASSERTION.

@pmonks
Copy link

pmonks commented Aug 28, 2025

@goneall or, if looping in legal adds too much latency, the tech team independently considers the approach of maintaining its own data list for these values, independent of the license list. That approach also addresses my primary concern (i.e. by modeling data as data, instead of hardcoding it in the grammar).

@swinslow
Copy link
Member

@pmonks NONE and NOASSERTION are not newly-added values for licensing fields. These have been available as values for SPDX licensing metadata since the v1.0 spec was released in 2010 / 2011. See https://spdx.dev/wp-content/uploads/sites/31/2023/09/spdx-1.0.pdf, for example section 4.12 on p. 19-20.

I strongly agree with you on not adding lots of new one-off identifiers. NONE and NOASSERTION don't fall into that bucket as they have always been part of SPDX.

Public domain statements are the only possible special case I can think of that could lead to an adjustment here in the future. This is an area where the community hasn't yet coalesced on how best to handle it. But any such change would be a major adjustment and not taken lightly / without significant discussion of the trade-offs.

You don't need to worry about PROPRIETARY getting added. There is no world in which that will be added as an identifier or a special-case syntax element (or at least, not for as long as I'm remaining involved with SPDX) :)

@pmonks
Copy link

pmonks commented Aug 29, 2025

@swinslow at the risk of sounding like a broken record, these values have not officially been part of SPDX License Expressions before now (despite being defined in other parts of the spec). This is trivially demonstrated by looking at the current formal definition of those expressions in SPDX spec v3.0.1 - note that neither NONE nor NOASSERTION appear anywhere on that page.

Adding them to expressions is clearly the right thing to do - I don't believe anyone (especially not me) is arguing against that. The issue here is how that gets done technically - I am convinced that hard coding them into the grammar is a mistake that will come back to bite us in future. I'm also reasonably confident that a better alternative is to represent this data as what it is: data. Whether that's in the license list with metadata to indicate these values' special semantics, or whether that's in some other data structure defined and managed entirely by the SPDX tech team, is neither here nor there. In my opinion these are both markedly better solutions than the one that's been implemented in this pull request.

@zvr
Copy link
Member Author

zvr commented Aug 29, 2025

@pmonks and @swinslow you are both correct: NONE and NOASSERTION were part of SPDX since the beginning, and until now they were not part of License Expressions.

Until 3.0, the license fields were having a value of type "License Expression or NONE or NOASSERTION". But this did not allow us to use NONE and NOASSERTION in an AND License Expression. That was the whole point of this change: to allow these special values to be used in expressions. And all the license fields now have a value of type "License Expression".

Now, as I've written before, these two special designations are the only ones in SPDX.
Instead of adding them here, we could create a separate list of "things that can be inside License Expressions that are not License, Exception, or Addition Identifiers". This list would have only these two entries: NONE and NOASSERTION.

But if we were to create such a list, we would have to somehow provide information on that other list about the permitted combinations ("this can only be used in AND expressions"), the grammar here would be more general, and everyone would have to implement the additional rules somehow. Or, since we are talking only about NONE and NOASSERTION that are only allowed in AND expressions, we could create the "list of things that can be inside AND License Expressions that are not Licenses or other compound License Expressions".

Instead, I believe that adding these two designations in the actual License Expression definition was the best (and easiest) way to achieve our goal. And we have to freeze 3.0, so that it takes its way towards ISO.

Of course, nothing prevents us to discuss alternatives and update whatever we decide that needs change at some point in the future.

@pmonks
Copy link

pmonks commented Aug 29, 2025

But if we were to create such a list, we would have to somehow provide information on that other list about the permitted combinations ("this can only be used in AND expressions")

@zvr this is an orthogonal issue that was already discussed on the tech team call, and while I was not actively involved in that conversation, IIRC the final decision was to simply document that restriction outside the grammar, in the non-machine-readable text of annex B. That approach seems to me to be equally applicable regardless of how NONE and NOASSERTION are implemented in the grammar itself (i.e. via hardcoding or as separate data), so I'm not sure how it has any relevance to my specific concern around how this is implemented in the grammar.

And we have to freeze 3.0, so that it takes its way towards ISO.

If we go with a list-managed-by-tech-team-that-is-NOT-the-license-list, then I don't think a data-oriented solution is any slower to implement than a hardcoded one, especially given the future proofing benefits it provides (which also pays off when future ISO recertifications are performed).

@bact
Copy link
Collaborator

bact commented Oct 17, 2025

Need to sync this in develop branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants