Skip to content

[2.0] fixes on schema and test resources - #1001

Open
jkowalleck wants to merge 38 commits into
2.0-devfrom
2.0-tests-init-fixes
Open

[2.0] fixes on schema and test resources#1001
jkowalleck wants to merge 38 commits into
2.0-devfrom
2.0-tests-init-fixes

Conversation

@jkowalleck

@jkowalleck jkowalleck commented Aug 4, 2026

Copy link
Copy Markdown
Member

fixes or related to

besides those fixes above, this is in the PR:

  • made the refLinkType inherit explicit
  • fixes the array nesting of extensibleProerties
  • consolidated milisecond timestamp for JSS
  • adds $comments
  • enhanced some docs
  • added test cases
    • for extensibleProperties
  • fixed valid test data
    • all test data that was just carried over from CDX 1.x was transferred to CDX 2.0schema
  • fixed invalid test data
    • removed invalid-component-choice-missing-name-2.0.json - as the name was optional or did not exist.
      ❓ was this intentional/correct

tests for the things are based on:

@jkowalleck jkowalleck mentioned this pull request Aug 4, 2026
4 tasks
@jkowalleck jkowalleck changed the title 2.0 tests init fixes 2.0 fixes Aug 4, 2026
@jkowalleck jkowalleck added defect CDX 2.0 related to release v2.0 labels Aug 4, 2026
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
@jkowalleck
jkowalleck force-pushed the 2.0-tests-init-fixes branch from a03e560 to 905e58a Compare August 4, 2026 15:36
jkowalleck added a commit that referenced this pull request Aug 4, 2026
- [x] Java tests - functional
- [x] JS tests - functional - WIP
- found some false-positives/false-negatives - due to errors in test
resources
- [x] JS tests - schema validate
  - includes #996
  - includes #992
- JS tests - semantics
  - [x] #998
  - [x] #995
- [x] PHP tests - functional

added tests only,
no schema/res fixes - they are prepared in 
- #997 
- #1001

---------

Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
jkowalleck and others added 23 commits August 4, 2026 19:00
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
@jkowalleck jkowalleck added the chore: QA A chore related to Quality Assurance label Aug 5, 2026
@jkowalleck jkowalleck added this to the 2.0 milestone Aug 5, 2026
@jkowalleck
jkowalleck marked this pull request as ready for review August 5, 2026 17:45
@jkowalleck
jkowalleck requested a review from a team as a code owner August 5, 2026 17:45

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

added new test file

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

added new test file

"$ref": "#/$defs/timestamp/$defs/withMilliseconds",
"title": "Created Timestamp",
"description": "The time at which this signature was originally created. The creator can use any time it deems most appropriate as the time the signature was created, but it MUST be precise to the nearest millisecond (exactly three digits after the decimal place in seconds). The created property MUST NOT be changed when creating a new version of the signature.",
"$comment": "Normative source: ITU-T X.590 clause 6.3.1",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

consolidated to #/$defs/timestamp/$defs/withMilliseconds

"title": "Modified Timestamp",
"description": "The time that this particular version of the signature was last modified. The creator can use any time it deems most appropriate as the time that this version of the signature was modified, but it MUST be precise to the nearest millisecond (exactly three digits after the decimal place in seconds). The modified property MUST be later than or equal to the value of the created property. If the created and modified properties are the same, then this is the first version of the signature.",
"$comment": "Normative source: ITU-T X.590 clause 6.3.1. Cross-field invariant: 'modified' MUST be greater than or equal to 'created'. JSON Schema 2020-12 cannot compare two sibling property values, so this constraint is NOT enforced by this schema and MUST be validated by the consuming tool or conformance suite.",
"pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\\.[0-9]{3}Z$"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

consolidated to #/$defs/timestamp/$defs/withMilliseconds

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

file was removed, since the relevant test case did not exist.
the componentCHoice does not require/have a name

❓ was this intentional/correct

Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
@jkowalleck
jkowalleck requested review from stevespringett and a lite review from Copilot August 5, 2026 18:48
@jkowalleck jkowalleck changed the title 2.0 fixes 2.0 fixes on schema and test resources Aug 5, 2026
@jkowalleck jkowalleck changed the title 2.0 fixes on schema and test resources [2.0] fixes on schema and test resources Aug 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the CycloneDX 2.0 JSON schemas and test fixtures to align with recent model changes (notably parties, signatures, extensible properties, and stricter schema semantics), and extends the JS semantic test suite to enforce additional schema invariants.

Changes:

  • Refactors many 2.0 test resources from legacy fields (e.g., publisher, supplier, manufacturer, authors, signature) to 2.0 structures (parties, signatures), and corrects cryptography-related shapes.
  • Tightens/clarifies schema semantics (e.g., additionalProperties: false in more places, explicit property presence in oneOf/anyOf branches, refLinkType usage).
  • Adds extensible-properties valid/invalid fixtures and adjusts JS semantic tests for the updated schema patterns.

Reviewed changes

Copilot reviewed 49 out of 49 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tools/src/test/resources/2.0/valid-standard-2.0.json Updates signature fixture to signatures[] and new JSS field names.
tools/src/test/resources/2.0/valid-service-2.0.json Migrates publisher to parties role-based representation.
tools/src/test/resources/2.0/valid-perspective-2.0.json Migrates supplier to parties role-based representation.
tools/src/test/resources/2.0/valid-patent-2.0.json Migrates manufacturer to parties and updates organization URL structure.
tools/src/test/resources/2.0/valid-machine-learning-considerations-env-2.0.json Migrates supplier/publisher to parties.
tools/src/test/resources/2.0/valid-machine-learning-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-license-name-with-text-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-license-name-with-licensing-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-license-name-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-license-id-with-text-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-license-id-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-license-expression-with-licensing-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-license-expression-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-license-choice-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-formulation-2.0.json Migrates publisher to parties.
tools/src/test/resources/2.0/valid-external-reference-2.0.json Migrates publisher to parties and adds new externalReference types.
tools/src/test/resources/2.0/valid-extensible-properties.json Adds a valid extensible-properties fixture (new file).
tools/src/test/resources/2.0/valid-cryptography-implementation-2.0.json Updates cryptography fixtures to match schema (e.g., arrays where required).
tools/src/test/resources/2.0/valid-cryptography-full-2.0.json Updates cryptography fixtures (e.g., arrays for refs/platform).
tools/src/test/resources/2.0/valid-cryptography-certificate-advanced-2.0.json Updates certificate fixtures and adds algorithm asset + algorithmRef arrays.
tools/src/test/resources/2.0/valid-cryptography-certificate-2.0.json Fixes ref and expands crypto assets; updates platform arrays.
tools/src/test/resources/2.0/valid-component-swid-full-2.0.json Migrates authors to parties with author role.
tools/src/test/resources/2.0/valid-component-swid-2.0.json Migrates authors to parties with author role.
tools/src/test/resources/2.0/valid-component-choice-xor-2.0.json Migrates supplier to parties for component-choice samples.
tools/src/test/resources/2.0/valid-component-choice-or-2.0.json Migrates supplier to parties for component-choice samples.
tools/src/test/resources/2.0/valid-component-choice-nested-2.0.json Migrates nested supplier to nested parties.
tools/src/test/resources/2.0/valid-component-choice-in-nested-components-2.0.json Migrates nested supplier to nested parties.
tools/src/test/resources/2.0/valid-component-choice-and-2.0.json Migrates supplier to parties for AND operator sample.
tools/src/test/resources/2.0/valid-bom-2.0.json Broad migration of manufacturer/supplier/authors/publisher to parties, including contacts and URLs.
tools/src/test/resources/2.0/valid-attestation-2.0.json Migrates multiple signature objects to signatures[] throughout.
tools/src/test/resources/2.0/invalid-extensible-properties.json Adds invalid extensible-properties fixture (new file).
tools/src/test/resources/2.0/invalid-component-choice-missing-name-2.0.json Removes an invalid test resource fixture.
tools/src/test/js/schema-v2/json-schema-semantic-tests.js Updates semantic tests for refLinkType exception and additionalProperties handling.
schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json Adds additionalProperties: false and fixes required-property existence assertions.
schema/2.0/model/cyclonedx-patent-2.0.schema.json Switches certain refs from refType to refLinkType.
schema/2.0/model/cyclonedx-party-2.0.schema.json Makes oneOf branches explicitly assert the required property exists.
schema/2.0/model/cyclonedx-metadata-2.0.schema.json Adds additionalProperties: false to an object schema.
schema/2.0/model/cyclonedx-license-2.0.schema.json Makes oneOf branches explicitly assert the required property exists.
schema/2.0/model/cyclonedx-jss_X590_2023_10-2.0.schema.json Consolidates millisecond timestamp handling and adds explicit property presence in anyOf.
schema/2.0/model/cyclonedx-formulation-2.0.schema.json Makes oneOf branches explicitly assert the required property exists.
schema/2.0/model/cyclonedx-declaration-2.0.schema.json Adjusts required fields in a oneOf branch (e.g., signatures).
schema/2.0/model/cyclonedx-data-2.0.schema.json Makes oneOf branches explicitly assert the required property exists.
schema/2.0/model/cyclonedx-cryptography-2.0.schema.json Refactors some oneOf branches/types and shifts refs to refLinkType.
schema/2.0/model/cyclonedx-component-2.0.schema.json Improves mutual-exclusion logic annotation and adds property presence to not.
schema/2.0/model/cyclonedx-common-2.0.schema.json Makes refLinkType inheritance explicit; refactors extensible-properties schema; adjusts base mixins; adds placeholder for organizationalEntityOrContact.
schema/2.0/model/cyclonedx-citation-2.0.schema.json Makes anyOf/oneOf branches explicitly assert required property exists.
schema/2.0/model/cyclonedx-annotation-2.0.schema.json Makes oneOf branches explicitly assert required property exists.
schema/2.0/model/cyclonedx-ai-modelcard-2.0.schema.json Removes redundant type alongside $ref.
schema/2.0/cyclonedx-2.0.schema.json Replaces root additionalProperties: false with unevaluatedProperties: false to support extensibility mixins.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread schema/2.0/model/cyclonedx-common-2.0.schema.json
Comment thread tools/src/test/js/schema-v2/json-schema-semantic-tests.js
Comment thread schema/2.0/model/cyclonedx-component-2.0.schema.json Outdated
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
@jkowalleck

jkowalleck commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

had Fable 5 analyze the state of the schema.

my query:

Analyze the JSON Schema structure under https://github.com/CycloneDX/specification/blob/2.0-tests-init-fixes/schema/2.0/cyclonedx-2.0.schema.json . Ignore all `-bundled` files.

Starting from the root schema , follow every $ref transitively through the files in  (e.g. cyclonedx-metadata, cyclonedx-component, cyclonedx-service, cyclonedx-dependency, cyclonedx-composition, cyclonedx-vulnerability, cyclonedx-annotation, cyclonedx-formulation, cyclonedx-declaration, cyclonedx-definition, cyclonedx-citation, cyclonedx-perspective, cyclonedx-common, cyclonedx-party, cyclonedx-license, cyclonedx-data, cyclonedx-cryptography, cyclonedx-ai-modelcard, cyclonedx-release-notes, cyclonedx-standard, cyclonedx-patent, cyclonedx-jss_X590_2023_10, cyclonedx-api) and check whether the schema makes sense in its current structure. Specifically verify:
Code

- Broken references: every `$ref` (relative file path + JSON pointer like `#/$defs/xyz`) resolves to an existing file and an existing $defs entry in that file. List any $ref that points to a missing file or missing definition.
- `$id` consistency: each file's $id matches its actual path/filename and the expected https://cyclonedx.org/schema/2.0/... convention.
Orphaned files/definitions: model files or $defs entries not reachable from the root schema (excluding the separate cyclonedx-api-2.0.schema.json entry point — check its refs too).
- Circular references that could be problematic, and duplicate definitions of the same concept in multiple files.
- Draft 2020-12 correctness: proper use of $defs, unevaluatedProperties interaction with allOf/$ref (note the root uses unevaluatedProperties: false together with allOf extensibleProperties — check whether this composition works as intended across files), missing $schema declarations, wrong keyword usage, invalid regex patterns, enum/const misuse.
- Naming/structural inconsistencies: inconsistent def naming, inconsistent title/description conventions, anything that looks off (e.g. typos in filenames like jss_X590 vs X.509).

Produce a report of concrete issues found, each with file path, JSON pointer location, and a suggested fix. Also state explicitly which aspects were checked and found to be fine.

I need the report in pastable markdown.

this are the results:

CycloneDX 2.0 JSON Schema Structure Review

Scope: branch 2.0-tests-init-fixes, root schema/2.0/cyclonedx-2.0.schema.json plus all 22
schema/2.0/model/*.schema.json files and schema/2.0/cyclonedx-api-2.0.schema.json.
All *-bundled* files were ignored. All 433 $ref occurrences were resolved transitively;
every file was validated against the JSON Schema 2020-12 meta-schema.


1. Concrete issues found

1.1 References that escape the schema/2.0/ tree (and have $id mismatches)

# File Location (JSON pointer) Issue
1 schema/2.0/model/cyclonedx-cryptography-2.0.schema.json #/$defs/cryptoProperties/properties/algorithmProperties/properties/algorithmFamily/$ref and .../ellipticCurve/$ref "../../cryptography-defs.schema.json#/definitions/…" points outside the versioned 2.0 tree to schema/cryptography-defs.schema.json. The pointer itself resolves (the target has definitions/algorithmFamiliesEnum and definitions/ellipticCurvesEnum), but: (a) the target is a draft-07 schema while all 2.0 schemas are 2020-12; (b) resolving the relative ref against the model file's $id yields https://cyclonedx.org/schema/cryptography-defs.schema.json, while the target declares $id: http://cyclonedx.org/schema/cryptography-defs.schema.json (http vs https mismatch — strict resolvers that key their registry by $id will fail); (c) it is unversioned, so 2.0 validation results can change whenever the shared file is regenerated. Fix: copy/generate a versioned, 2020-12 $defs-based snapshot into schema/2.0/ (e.g. schema/2.0/cyclonedx-cryptography-defs-2.0.schema.json) with an https://cyclonedx.org/schema/2.0/... $id, and reference that.
2 schema/2.0/model/cyclonedx-license-2.0.schema.json #/$defs/license/properties/id/$ref "../../spdx.schema.json" — same class of problem: target is draft-07, unversioned, outside schema/2.0/, and declares $id: http://cyclonedx.org/schema/spdx.schema.json while the ref resolves to the https:// URI. Fix: ship a versioned SPDX enum snapshot under schema/2.0/ (as 1.x does with a sibling spdx.schema.json in the same directory) or at minimum align the $id scheme.

These two are the only refs that do not stay within schema/2.0/; every other $ref (relative path + #/$defs/... pointer) resolves to an existing file and an existing definition.

1.2 Orphaned / dead definitions

# File Location Issue & suggested fix
3 model/cyclonedx-common-2.0.schema.json #/$defs/organizationalEntityOrContact Content is literally { "$comment": "TODO" } — an unfinished stub, referenced by nothing. As a schema it is true (accepts anything). Fix: implement it (e.g. anyOf of organizationalEntity / organizationalContact) or delete it before release.
4 model/cyclonedx-common-2.0.schema.json #/$defs/baseObject A "base object for all CycloneDX entities" mixin (extensibleProperties + properties + externalReferences) that no schema composes. Its own $comment describes an architecture ("concrete leaf schemas composing this mixin must close themselves with unevaluatedProperties: false") that is not implemented anywhere. Fix: either wire it into the entity definitions or remove it. See also issue 8 — this orphan is the symptom of a larger design gap.
5 model/cyclonedx-common-2.0.schema.json #/$defs/base64 Unreferenced. attachment.content is a plain string and does not use it even when encoding: "base64" is set. Fix: reference it from attachment (e.g. via if/then on encoding) or remove it.
6 model/cyclonedx-common-2.0.schema.json #/$defs/timestamp Unreferenced. Every consumer needing a timestamp uses inline format: date-time, and the JSS file carries its own, stricter timestamp def. Fix: make the model files reference common#/$defs/timestamp (or delete it). Note its regex is also weaker than the JSS one (accepts 2023-13-99T…) — see issue 10.
7 schema/2.0/cyclonedx-api-2.0.schema.json whole file An empty shell: type: object, empty $defs, no properties/required — it validates any JSON object. The README describes it as "the normative API-focused schema", which it currently isn't. It references no model files at all. Fix: flesh it out or clearly mark it as a placeholder in the README.

There are no orphaned model files — all 22 model files are reachable from the root schema.

1.3 unevaluatedProperties / extensibility composition

# File Location Issue & suggested fix
8 root + all model files root #/allOf + #/unevaluatedProperties; e.g. component, service, vulnerability… defs The root composition itself is correct: in draft 2020-12, unevaluatedProperties: false does see through allOf/$ref, so root-level properties and the ext:* patternProperties from extensibleProperties both remain allowed while everything else is rejected. However, the pattern is only applied at the document root. All nested entity objects (component, service, vulnerability, party, hash, etc. — 100+ objects) are closed with additionalProperties: false and do not compose extensibleProperties. Consequently ext:* extension properties are legal only at the BOM top level, contradicting the extensibleProperties description ("enables organizations … to safely introduce custom properties") and the mixin comments in common (issues 3–4). Fix: decide the intended granularity. If entities should be extensible: give each entity allOf: [{$ref: …extensibleProperties}] and replace additionalProperties: false with unevaluatedProperties: false (this is exactly what the orphaned baseObject was built for). If only the root should be extensible: update the extensibleProperties description/comments and delete baseObject.
9 model/cyclonedx-jss_X590_2023_10-2.0.schema.json #/$defs/signatureObject/unevaluatedProperties unevaluatedProperties: true is a no-op — it is identical to omitting the keyword. The $comment explains the openness is intentional (X.590 §6.2 allows extra metadata), so the behaviour is fine, but the keyword adds noise and suggests a misunderstanding. Fix: drop the keyword and keep the $comment, or keep it only if you want an explicit marker (then say so in the comment).

1.4 Duplicate definitions of the same concept

# Concept Files Issue & suggested fix
10 timestamp common#/$defs/timestamp vs jss_X590…#/$defs/timestamp Two different regexes for the same concept: common's ^\d{4}-\d{2}-\d{2}T…$ accepts invalid dates (2023-13-99); JSS's validates month/day/hour ranges. Common's is also completely unused (issue 6). Fix: keep one canonical def (JSS one is normative to X.590 and may stay, but common should adopt equivalent strictness) and reference it.
11 postalAddress common#/$defs/postalAddress vs party#/$defs/postalAddress Two divergent address models are both in active use: party's adds isoCode and coordinates; common's is used from organizationalEntity. Same title, different shapes → the same real-world address validates differently depending on which parent object holds it. Fix: keep one (party's superset) and have common $ref it, or move it wholly into common.
12 identifier component, party, jss_X590… (each #/$defs/identifier) Three unrelated concepts share one def name: component = "identifiers asserted by a party", party = "authority-issued identifier (scheme/value)", JSS = "UUID". Not a resolution problem (refs are file-scoped) but confusing for readers and for bundlers/codegen that flatten names. Fix: rename to assertedIdentifier / authorityIdentifier / signatureId (or similar).
13 hashAlgorithm common vs jss_X590… common = enum of SHA-256-style names; JSS = free-form IANA lowercase (sha-256) pattern. Same name, incompatible value spaces. Justifiable (X.590 mandates IANA names) but deserves a rename (e.g. ianaHashAlgorithm in JSS) or a $comment cross-reference.
14 mediaType common#/$defs/mediaType vs component#/$defs/component/properties/mime-type Component's mime-type re-declares the identical pattern ^[-+a-z0-9.]+/[-+a-z0-9.]+$ inline instead of $ref-ing common#/$defs/mediaType; the property is also named mime-type while everything else says "media type". Fix: $ref the common def; consider renaming the property (breaking) or at least noting the alias.
15 party vs organizationalEntity party-2.0 vs common-2.0 Two parallel "who" models coexist: the rich party/organization/person/persona model (referenced from exactly one place: component#/$defs/…parties) and the legacy organizationalEntity/organizationalContact (referenced ~20×, incl. metadata). If party is the 2.0 direction, most of the spec doesn't use it yet. Fix: converge (e.g. make organizationalEntity an alias/$ref into the party model), or document the intended split.

1.5 Naming / structural inconsistencies

# File / location Issue & suggested fix
16 model/cyclonedx-jss_X590_2023_10-2.0.schema.json (filename + $id) The standard is ITU-T X.590 (JSON Signature Scheme) — the filename drops the dot (X590) and mixes snake_case (jss_X590_2023_10) into an otherwise all-kebab-case directory (ai-modelcard, release-notes, …). It is not a typo for X.509, but it reads like one. Fix: rename to e.g. cyclonedx-jss-x590-2.0.schema.json (edition date in the file's $comment/description, not the filename) and update $id plus the one inbound ref from common.
17 Titles across model files Convention is CycloneDX <Thing> Model (Annotation, Citation, Common, …) but two deviate: CycloneDX AI Model Card and CycloneDX Model for JSON Signature Scheme (JSS). Fix: normalize (e.g. CycloneDX AI Model Card Model is awkward — pick and document one convention).
18 root #/properties/specFormat Single-value "enum": ["CycloneDX"] — in 2020-12 the idiomatic form is "const": "CycloneDX". Same for ai-modelcard energyMeasure.unit (["kWh"]), co2Measure.unit (["tCO2eq"]) and common attachment.encoding (["base64"]). Fix: use const (non-breaking, purely stylistic).
19 root #/properties/specVersion Only type: string with an example of "2.0"any string validates ("1.4", "banana"). Every 1.x schema pins this with an enum. Fix: "const": "2.0" (or an enum if patch versions are anticipated).
20 model/cyclonedx-jss_X590_2023_10-2.0.schema.json #/$defs/timestamp/$defs/withMilliseconds A $defs block nested inside another definition, referenced via the unusual pointer #/$defs/timestamp/$defs/withMilliseconds. Legal, and the $comment marks it internal, but it is the only place this idiom is used and some tooling (doc generators, bundlers) handles nested $defs poorly. Fix (optional): hoist to a top-level $defs/timestampWithMilliseconds.
21 model/cyclonedx-definition-2.0.schema.json The file exists to hold a single $defs/definitions wrapper (standards + patents). Also note the root BOM property is itself called definitions — a domain term that collides visually with the JSON-Schema keyword; inherited from 1.6, so acceptable, but the def-named-definitions-inside-$defs in this file compounds the confusion. Fix (optional): fold into standard/patent files or rename the def.

1.6 Circular references

# Cycle Assessment
22 cyclonedx-component-2.0cyclonedx-ai-modelcard-2.0 (component → modelCard/graphicsCollection; ai-modelcard → component#/$defs/componentData) The only cross-file cycle. Harmless for validation (recursion is data-bounded), but it defeats simple topological bundling/codegen. Fix (optional): move componentData (and friends) into cyclonedx-data-2.0.schema.json, which already exists for that purpose — this would break the cycle cleanly.
23 Self-recursion inside component (children/pedigree), formulation (workflow steps), JSS (signatureObject counter-signature chain), extensibleProperties/propertyValue All intentional and well-formed; no action needed.

2. Aspects checked and found to be fine

  • $ref resolution: all 433 refs resolve; every #/$defs/... pointer targets an existing definition. No dangling pointers within schema/2.0/. The only caveats are the two out-of-tree targets (issues 1–2).
  • $id consistency: all 24 files declare $id exactly matching https://cyclonedx.org/schema/2.0/<path> for their actual path/filename. No mismatches inside the 2.0 tree.
  • $schema declarations: present in every file, all https://json-schema.org/draft/2020-12/schema. No missing or mixed-draft declarations within the 2.0 tree.
  • Meta-schema validity: every file passes validation against the 2020-12 meta-schema.
  • Orphaned files: none — all model files are reachable from the root. Apart from the four $defs entries in common (issues 3–6), every definition in every file is referenced at least once.
  • $defs usage: consistently $defs (never legacy definitions) in all 2.0 files; the "definitions" hits in the root and definition model are domain property/def names, not the keyword.
  • Root unevaluatedProperties: false + allOf composition: semantically correct at the root — draft 2020-12 annotation flow makes the ext:* patternProperties from the referenced extensibleProperties count as "evaluated". (The gap is coverage, not correctness — issue 8.)
  • Regex patterns: all 24 pattern/patternProperties expressions compile and use only ECMA-262-safe constructs (no lookbehind, no \p without flags, etc.). Escaping is correct.
  • Enum/const misuse: no duplicate enum values, no type-inconsistent enums; only the stylistic single-value enums noted in issue 18.
  • Keyword usage: no draft-04 leftovers (boolean exclusiveMinimum, id, etc.); format values used (date, date-time, idn-email, iri-reference, uri, uuid) are all standard 2020-12 vocabulary; if/then/else, prefixItems-free arrays, and patternProperties are used correctly.
  • Model-file guard convention: every model file consistently uses root "type": "null" so the file root cannot accidentally be used as a document schema — applied uniformly across all 22 files.
  • Dependency graph: clean layering otherwise — common is the shared base (its only dependency is the JSS file), root fans out to the 13 top-level model refs, and the one problematic cycle is issue 22.

3. Summary

The modular structure is fundamentally sound: refs resolve, $ids are consistent, and the files are
valid 2020-12. The material problems are (a) the two out-of-tree, cross-draft, http/https-mismatched
external refs
(crypto-defs, SPDX), (b) the extensibility architecture being only half-built
(baseObject orphaned, ext:* only usable at the root while every nested object is closed with
additionalProperties: false), (c) the empty API entry point, and (d) several divergent duplicate
definitions
(postalAddress, timestamp, party-vs-organizationalEntity) that will produce
inconsistent validation of identical data.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

removed the test case, since the name was not required at all ...

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

Labels

CDX 2.0 related to release v2.0 chore: QA A chore related to Quality Assurance defect

Projects

None yet

2 participants