fix: lexicon framework terms - #540
Merged
eddie-knight merged 3 commits intoAug 27, 2026
Merged
Conversation
…ries Each framework was defined twice: once in metadata.yaml as a mapping-reference (id, title, version, url, description) and again in lexicon.yaml as a term. The compiled document rendered both, with two independently maintained descriptions, and the two files were joined only by string coincidence -- template.md piped each control's framework ID through addLinks, which matched it against lexicon terms and synonyms and silently emitted bare text when nothing matched. Four of the fourteen mapped frameworks were already unlinked that way (Scorecard, ISO-18974, UKSSCOP, BSI-TR-03185-2), and lexicon.yaml carried two entries both titled "Proactive Software Supply Chain Risk Management Framework", the second holding OWASP SAMM's definition. Link framework relations directly to the External Frameworks table row instead, giving each row a stable anchor, and delete the eleven duplicated lexicon entries. All fourteen mapped frameworks now resolve. The entry for Supply-chain Levels for Software Artifacts stays: its SLSA synonym is a live auto-link target in OSPS-BR criteria text. Add two validator checks so this cannot drift again silently: a mapping document's target reference must be declared in the catalog metadata, and lexicon terms must be unique. Signed-off-by: Eddie Knight <knight@linux.com>
DORA, NIS2, CSbDP, CSAG, USCTM and MAF were declared as mapping-references but no mapping document has ever targeted them. They came over in the Gemara v1 migration (ossf#494) from the pre-migration frameworks.yaml, where they were declaration-only as well. The compiled catalog is published to grc.store on release, so each one would ship as a framework reference a consumer could resolve but never match against, and each rendered a row in the External Frameworks table that no control could link to. The source material is not lost. The crosswalk workbook in docs/ keeps a sheet per framework, and four of them are substantially filled in -- though none reference a single OSPS control ID, so the crosswalk itself was never started. Re-add each reference alongside its mapping document. Every remaining reference now has exactly one mapping document, and every row in the External Frameworks table is the target of at least one control relation. Signed-off-by: Eddie Knight <knight@linux.com>
funnelfiasco
previously approved these changes
Aug 27, 2026
The mapping-reference check exempted the empty string, which is the one value that fails invisibly: both `validate` and `cue vet` pass while the renderer drops the document from the relations and the crosswalk without a word. Blanking one reference-id removed all 9 SLSA relations from the compiled document and left its table row orphaned, with no error. - Drop the `fw != ""` guard so an empty ID is an error like any other undeclared one. - Add the reverse check: a mapping-reference declared in metadata with no mapping document behind it renders a row nothing can link to. This is the state the previous commit cleaned out by hand. - Compare lexicon names case-folded and across synonyms. addLinks resolves a name to the first entry declaring it and asLink folds terms into anchors, so names differing only by case share one destination. Ownership is tracked per entry, so two entries sharing a term still collide while a synonym repeating its own term stays allowed. - Constrain the reference ID shape in CUE, on both the catalog metadata and each mapping document's target reference, so an ID with a space cannot render a broken anchor. - Drop the two lexicon synonyms the stricter check rejects: Vulnerability Reporting claimed Coordinated Vulnerability Disclosure, which is its own entry with a different definition, and the SLSA entry repeated its own term. - Cover both new checks with tests, and drop two spellcheck words left over from the removed references. Rendered output is byte-identical, and anchors remain 14/14.
funnelfiasco
approved these changes
Aug 27, 2026
evankanderson
approved these changes
Aug 28, 2026
evankanderson
left a comment
Contributor
There was a problem hiding this comment.
It looks like this changes the format of anchor references, but that should only take effect for new baseline versions because of the way we check in the compiler outputs for existing versions.
eddie-knight
added a commit
that referenced
this pull request
Aug 28, 2026
* feat: auto-generate mapping document links and crosswalk on the website Each compiled version page's External Frameworks table now links the framework's Gemara mapping document on grc.store, and the reverse crosswalk generator (previously unused by the site) renders one section per framework and is wired into the Pages build as devel-crosswalk.md. A new --artifact-version compile flag pins the grc.store links to a published release tag; unset, they point at the latest version. Signed-off-by: Eddie Knight <knight@linux.com> * Add 2026-08-26 release candidate Compiled RC page set (controls, checklist, and the new external framework crosswalk), linked from the versions list. Release notes for 2026-08-26 are drafted but stay commented out until the release, which will also promote the page to Current Version per the usual process. Signed-off-by: Eddie Knight <knight@linux.com> * Add make dev for local site preview Compiles the devel pages the same way web-publish.yml does (including the new crosswalk) and serves the site with Jekyll at 127.0.0.1:4000. devel-crosswalk.md joins the other generated devel pages in .gitignore. Signed-off-by: Eddie Knight <knight@linux.com> * fix: guard artifactURL against empty ids; regenerate RC pages post-rebase An empty artifact id now yields an empty URL from artifactURL rather than a link to the bare grc.store namespace, with a test covering the pinned, unpinned, and empty cases. The 2026-08-26 RC page is regenerated against main after #540, which removed the unmapped framework metadata rows and the framework lexicon entries (including the duplicate PSSCRM term) and linked each per-control framework relation to its row in the External Frameworks table — where the new Mapping Document column links to grc.store. Signed-off-by: Eddie Knight <knight@linux.com> * fix: drop SLSA lexicon entry and dead CI/CD anchors SLSA was the one framework #540 left in the lexicon, so it still rendered as a glossary entry alongside its External Frameworks row. The validator now rejects any lexicon term or synonym that shadows a mapping-reference id, so a framework can't reappear in the glossary. asLink mapped every non-letter to '-', but kramdown deletes '/' when deriving a heading id, so each [CI/CD Pipeline] link pointed at the dead anchor #ci-cd-pipeline instead of #cicd-pipeline. Drop '/' the way '.' already is, with a test pinning the anchor scheme. RC page regenerated; historical release pages are left as released. Signed-off-by: Eddie Knight <knight@linux.com> * Release version 2026.08.28 of the Baseline Converts the release-candidate pages to the final release: pages recompiled with grc.store mapping links pinned to v2026.08.28, nav and index updated to make v2026.08.28 the current version, and the drafted release notes published. * docs: document the release steps in CONTRIBUTING.md * docs: drop release steps from CONTRIBUTING.md in favor of the release issue template * docs: sync release issue template with current release process --------- Signed-off-by: Eddie Knight <knight@linux.com>
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.
This removes duplicate metadata/lexicon entries and removes references that are not in use.
Also adjusts the template to accommodate:
Edit: Claude recommended some CI changes to avoid drift in the future. See below for that info.
🤖
This removes duplicate metadata/lexicon entries and references that are not in use, and hardens the checks that keep them from coming back.
What the template change actually fixes
Framework relations rendered through
addLinks, which produced reference-style links into the lexicon glossary rather than the External Frameworks table. Only 9 of the 14 frameworks linked at all, and two of those linked wrongly:**BSI-TR-03185-2**,**PSSCRM**,**Scorecard**,**UKSSCOP**rendered as bare bold text, having no lexicon entry.**ISO-[18974][OpenChain]**was mangled. The OpenChain entry carried the synonym18974, andaddLinkssubstring-matched it inside the identifierISO-18974, splitting the ID and emitting a link in the middle of it.**[SAMM][Proactive Software Supply Chain Risk Management Framework]**pointed at the wrong framework. That title was the duplicated lexicon term, so SAMM's link resolved to P-SSCRM's glossary anchor — and the duplicate caused the same link definition to be emitted twice in one document.So the duplicate lexicon entry was not cosmetic: it produced a wrong link destination in published output.
The template changes:
:120switches the link source from lexicon lookup to a direct anchor — this is what replaces the deleted entries.:136creates the anchor that line points at. Nothing could link into the External Frameworks table before; every row was unaddressable. Without this line,:120produces dead links instead of working ones.All 14 frameworks now render uniformly as
[ID](#fw-ID)into the table, with no reference-style or mangled links remaining.Validation
Routing framework names through the lexicon was the wrong mechanism — a short synonym could corrupt a longer identifier. Direct anchors remove that class of bug, and the new checks keep the data behind them honest:
validateandcue vetpass while the renderer drops the document from the relations and the crosswalk in silence.addLinksresolves a name to the first entry declaring it andasLinkfolds terms into anchors. This required dropping two more synonyms:Vulnerability ReportingclaimedCoordinated Vulnerability Disclosure, which is its own entry with a different definition, and the SLSA entry repeated its own term.Both new checks are covered by tests. Rendered output is byte-identical to before the validation changes, and anchors remain 14/14.