SBOM Format Crosswalk (CycloneDX to SPDX)
The field-by-field map between the CycloneDX 1.6 and SPDX 2.3 documents in this category, plus the five invariants a correct conversion preserves and the three things it legitimately loses. Every package, version, hash and licence is fictional — the tree describes nothing real.
# SBOM format crosswalk — CycloneDX 1.6 vs SPDX 2.3
> SAMPLE — fictional supply-chain data. Every package, registry, version, hash, licence, advisory identifier and signature in this document is invented.
Both serialisations in this category describe the same fictional tree: `orchard-gateway` 4.2.0 and nine invented dependencies. This table is the field map a converter has to implement, and the checklist to diff a conversion against.
| Concept | CycloneDX 1.6 | SPDX 2.3 | Value in these fixtures |
| --- | --- | --- | --- |
| Document id | `serialNumber` (urn:uuid) | `documentNamespace` + `SPDXID` | distinct per file, derived from a fixed seed |
| Root subject | `metadata.component` | `documentDescribes` / DESCRIBES | `@orchard-example/gateway` 4.2.0 |
| Component id | `bom-ref` (purl) | `SPDXID` (`SPDXRef-Package-*`) | one per package |
| Package URL | `purl` | `externalRefs` PACKAGE-MANAGER/purl | identical strings |
| Licence | `licenses[].license.id` or `.expression` | `licenseConcluded` / `licenseDeclared` | same SPDX ids |
| Integrity | `hashes[].alg` + `.content` | `checksums[].algorithm` + `.checksumValue` | same SHA-256 hex |
| Graph edge | `dependencies[].dependsOn` | `Relationship … DEPENDS_ON …` | 10 edges |
| Supplier | `supplier.name` | `PackageSupplier: Organization:` | Example Softworks (fictional) |
| Vulnerabilities | `vulnerabilities[]` (VEX in BOM) | separate VEX/CSAF document | 4 SAMPLE advisories |
## What a correct conversion preserves
1. Component count: **9** dependencies plus the root application.
2. Edge count: **10** dependency relationships.
3. The two diamonds — `example-logger@3.4.1` reached by three parents, `example-json-path@2.0.5` by two — stay single nodes.
4. Every SHA-256 value is byte-identical across formats.
5. Compound licence expressions are not flattened to a single identifier.
## What it legitimately loses
- CycloneDX `services` and `compositions` have no direct SPDX 2.3 equivalent.
- SPDX `snippets` have no CycloneDX equivalent.
- SPDX `LicenseRef-*` extracted text must be carried as a CycloneDX `licenses[].expression` plus a property, or it is dropped.
Specifications
- Seed
- 51200
- Sample Only
- true
- Format
- Markdown
- Mapped Fields
- 9
- Invariants
- 5
- Line Endings
- LF
Testing contract
Reference control- Scenario
- Score an SBOM converter against a documented expectation instead of eyeballing the output.
- Expected result
- A conversion that keeps 9 components, 10 edges, both diamonds, identical SHA-256 values and unflattened licence expressions passes all five invariants.
What is a .md file?
Markdown (MD) is a lightweight plain-text markup language that uses simple punctuation conventions to denote headings, lists, links, emphasis, and code. It is designed to be readable as-is and to convert cleanly to HTML. It is widely used for documentation, READMEs, and content authoring.
How to use this file
Use an example Markdown file to test parsers and renderers, verify GitHub-Flavored Markdown extensions like tables and fenced code, and exercise HTML-conversion pipelines.
How to use this file for testing
“SBOM Format Crosswalk (CycloneDX to SPDX)” is a deterministic Novus Examples fixture for Conversion testing, Editor testing. The same content exported across many formats and linked as a group, so you can convert one and diff against the expected twin.
Documented properties for this file: seed 51200 · LF · Markdown. Compare results against paired or grouped companions on this page when present (clean↔damaged, searchable↔scanned, or format twins) so scores stay reproducible across runs.
Download the file once, keep the path stable in CI or local scripts, and treat the spec table as the contract: dimensions, seeds, field lists, and roles are intentional. Corrupt or invalid samples are labelled as such — expect parsers to fail loudly rather than silently accept them.
SBOM, lockfile, provenance, and advisory fixtures describe the same fabricated component tree across formats, so a converter or scanner can be diffed against a known answer. Every package name, version, hash, and advisory ID is invented — never treat a finding here as real.
Code examples
import markdown # pip install markdown
html = markdown.markdown(open("sbom-format-crosswalk.md").read())
print(html[:200])Related files
- mmdDependency Graph (Mermaid Flowchart)The dependency graph as Mermaid, for embedding in Markdown documentation — labelled edges carry the declared range and a classDef highlights the two diamond joins. Every package, version, hash and licence is fictional — the tree describes nothing real.

- dotDependency Graph With Diamonds (Graphviz DOT)The same diamond graph as Graphviz DOT, with edge labels carrying the declared semver range and the two diamond joins filled — renderable to SVG and diffable against the JSON twin. Every package, version, hash and licence is fictional — the tree describes nothing real.

- mdProvenance Verification Runbook (Markdown)The five checks a verifier must perform against the attestation fixtures in this category, and the exact result each one should produce — including the two that are meant to fail. Every package, version, hash and licence is fictional — the tree describes nothing real.

- mdVersion Conflict and Diamond Report (Markdown)The written explanation of both diamonds in this category — the one that resolves to a single shared node and the peer conflict that forces a nested duplicate — with the four assertions a resolver test should make. Every package, version, hash and licence is fictional — the tree describes nothing real.

- mdVulnerability Triage Report (Markdown)The human-readable end of the pipeline: a triage report that records a decision and a reachability path for each of the four SAMPLE findings, matching the states asserted by the VEX documents here. Advisory identifiers use the invented NOVUS-SAMPLE namespace with SAMPLE-CVE aliases; no identifier here refers to a published CVE, GHSA or OSV record, and no package named exists.

- lockyarn.lock (Classic v1)A Yarn 1 lockfile in its own line-oriented grammar — quoted descriptor headers, two-space indented fields, resolved URLs with a SHA-1 fragment — which looks like YAML but is not. Every package, version, hash and licence is fictional — the tree describes nothing real.

Generated by generation/supply_chain.py. Free for any use, no attribution required — license.