Fix SPDX profile resolution: split lookup_table onto its own node - #174
Merged
Conversation
The KV deploy after #173 failed one generated fixture: secid:reference/spdx.dev/spdx#ai resolved to .../model/ai/ai/ instead of .../model/AI/AI/. The profile node accepted both spellings — the capitalised model path (AI) and the lowercase core:ProfileIdentifierType value written into profileConformance (ai) — and relied on lookup_table taking priority over the {profile} URL template for the lowercase set. The deployed resolver builds from the template first, so the lowercase input was substituted verbatim into a path that does not exist. Split into two sibling nodes, matching the shape already proven by weakness/owasp.org: the capitalised node keeps the template, and the ProfileIdentifierType node carries lookup_table alone with {url, title} values and no template. Patterns stay case-sensitive, so the two remain mutually exclusive. Licensing appears only on the capitalised node — it has a /model/Licensing/ page but is not a ProfileIdentifierType value. Verified by regenerating SecID-Service's src/registry.ts from this working tree and running its suite: 388/388 pass, including all 28 spdx.dev and cyclonedx.org fixtures. Previously 386 passed, 1 failed.
This was referenced Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #173. The KV upload after that merge failed on one generated fixture, so the live resolver did not pick up either entry.
The failure
The profile node accepted both spellings the source uses — the capitalised model/documentation path (
AI) and the lowercasecore:ProfileIdentifierTypevalue written into a document'sprofileConformancefield (ai) — and relied onlookup_tabletaking priority over the{profile}URL template for the lowercase set, asREGISTRY-JSON-FORMAT.mddescribes.The deployed resolver builds from the template first, so
aiwas substituted verbatim and produced.../model/ai/ai/, which does not exist.The fix
Split into two sibling nodes, matching the shape already proven by
weakness/owasp.org:^(AI|Build|...|Licensing|...)${profile}template^(ai|build|...|software)$lookup_tableonly,{url, title}values, no templatePatterns stay case-sensitive, so the two are mutually exclusive — verified across all enumerated values.
Licensingstays on the capitalised node only: it has a/model/Licensing/page but is not aProfileIdentifierTypevalue, so it never appears inprofileConformance.Worth noting the documented precedence rule (
lookup_tablewins overurlon the same node) does not hold in the deployed resolver. This PR routes around it rather than depending on it; whether the resolver or the doc should change is a separate question.Verification
Rather than guess twice, I regenerated SecID-Service's
src/registry.tsfrom this working tree and ran its suite locally:spdx.devandcyclonedx.orgfixtures —#ai,#AI,#dataset,#Datasetall resolve to the correct capitalised URLcheck-pattern-breadth.pyPASS, no new exceptionsvalidate-subtypes.pyPASSschemas/registry-namespace.schema.json