# Vercy AI instruction - YAML 1.2 (JSON-compatible) { "vercy": "1.0-draft", "publication": { "status": "published", "adjudicationStatus": "reviewable-draft", "publishableCanonical": false, "generatedAt": "2026-08-26T10:11:57Z", "synthesisSha256": "7174c9d4be0a236da9d68c01110080213c973a9f28babb45064adea63ffa9cbb", "providerMode": "dual-provider", "providers": [ "Claude", "Grok" ], "waivedProviders": [] }, "metaModel": { "id": "WM-SFT-007", "registryId": "vr.wm-sft-007", "name": "Software Component / Package", "version": "0.3.0-research.1", "previousVersions": [], "entryKind": "entity", "family": "World Models", "category": "Information and virtual systems", "industry": [ "Cross-industry" ], "domain": [ "INF.SFT.PKG" ], "tags": [ "software", "component", "package", "inf.sft.pkg" ], "status": "published" }, "canonicalUrl": "https://ver.cy/models/wm-sft-007-software-component-package/", "sourceUrl": "https://github.com/ver-cy/world-models/tree/feat/mega-model-registry/research/runs/wm-sft-007", "model": { "registry_id": "vr.wm-sft-007", "model_id": "WM-SFT-007", "name": "Software Component / Package", "entry_kind": "entity", "purpose": "Provide the format-neutral context an agent needs to identify, classify, verify, compose, govern and operate a versioned, distributable software component or package release used as a dependency.", "scope_statement": "This model covers the identifiable software component or package as a distributable unit: its project-level and release-level identity, version designation, contained and depended-upon composition, origin and build provenance, licensing and regulatory obligations, lifecycle state, vulnerability exposure, distribution channel and the provenance of every assertion made about it. It deliberately stops at the boundary of the consuming product, the SBOM document, the advisory record and the running deployment, each of which is a sibling or parent model. Storage and interface (JSON, YAML, Markdown, Git, MCP, MongoDB) are projections of this model, never its semantics.", "in_scope": [ "Project-level identity (ecosystem type, namespace, name) and release-level identity (version, distribution variants, content digests).", "Cross-scheme identifier alignment: purl, CPE, SWID, content identifiers, OCI descriptors and registry-native keys.", "Declared dependency constraints, resolved dependency closures, contained files, bundled subcomponents and pedigree or derivation.", "Origin and supply-chain provenance: supplier, author, manufacturer and distributor roles, source revision linkage, build attestation and signature verification.", "Declared and concluded licensing, attribution and notice obligations attaching to redistribution.", "Release lifecycle state (pre-release, published, deprecated, yanked, withdrawn, removed), support window and replacement path.", "Vulnerability affectedness of a specific version, exploitability status, remediation decisions and time-bounded exceptions.", "Distribution channel, registry of record, retrieval location, availability, unpublish and retention behaviour.", "Assertion-level provenance: who asserted a fact, from which source, with what evidence and confidence, at which event and observation time." ], "out_of_scope": [ "The composed software product or service that consumes the component, and its architecture (WM-SFT-001).", "The SBOM document itself, its structure, exchange, signing and distribution (WM-SFT-012); only the reference edge and coverage claims remain here.", "Vulnerability and advisory records as first-class entities (CVE, GHSA, OSV entries); only the affectedness edge for a version is in scope.", "Source repository, branch and commit management, code review and contribution process.", "Build platform, pipeline and runner configuration as entities; only the emitted provenance predicate and its subject digest are referenced.", "Deployed or running instances, hosts, containers at runtime and operational telemetry.", "Legal-entity master data for suppliers, maintainers and stewards; only the role edge is in scope.", "Licence texts, licence drafting and legal interpretation; only the expression and derived obligations are in scope.", "Cryptographic key material, trust roots, key issuance and rotation procedures.", "Hardware bills of material and non-software components." ], "boundary_notes": [ { "neighbor": "WM-SFT-001 Software Product / Service", "distinction": "A product or service is the marketed and operated whole; a package is a versioned distributable unit reusable across many products. SPDX models both as Package instances distinguished only by purpose vocabularies, so the distinction must be carried by the composition edge, not by the class.", "source_refs": [ "SRC-001", "SRC-018" ] }, { "neighbor": "WM-SFT-012 Software Bill of Materials", "distinction": "An SBOM is a document asserting a component set at a point in time; SPDX models it as a distinct Sbom class. The component exists independently of any SBOM, so SBOM structure, completeness and exchange belong to the sibling model.", "source_refs": [ "SRC-018", "SRC-005" ] }, { "neighbor": "Vulnerability / advisory record (OSV, CVE, GHSA)", "distinction": "The OSV entry is the authority-published record with its own identifier, aliases, ranges and modification time. This model stores only the resolved verdict for a concrete version plus the evidence of that resolution.", "source_refs": [ "SRC-008" ] }, { "neighbor": "Build or pipeline run", "distinction": "SLSA provenance describes the build run, its builder identity and parameters. The package holds the subject digest and the attestation reference; the run itself is a separate event entity.", "source_refs": [ "SRC-006", "SRC-007" ] }, { "neighbor": "Source code revision (VCS commit)", "distinction": "purl types such as github and golang can address version-control locations, but a revision is not a distributable release with its own distribution artifacts and lifecycle state; the two must not be conflated.", "source_refs": [ "SRC-002" ] }, { "neighbor": "Product-class identifier (CPE)", "distinction": "CPE names classes of IT products for platform enumeration and vulnerability matching; it does not address a specific downloadable artifact. purl does. Mapping between them is lossy and must be recorded as an alignment.", "source_refs": [ "SRC-011", "SRC-003" ] }, { "neighbor": "Installed software asset (SWID tag)", "distinction": "SWID tags describe software installed on an endpoint, including patch and supplemental tags for asset management. Endpoint installation state is asset data, not package identity.", "source_refs": [ "SRC-012" ] }, { "neighbor": "Container image / OCI artifact", "distinction": "An OCI image is addressed by a content descriptor digest and may also carry a purl of type oci. It extends package identity with layered content addressing rather than replacing it.", "source_refs": [ "SRC-013", "SRC-002" ] } ] }, "sources": [ { "id": "SRC-001", "title": "SPDX Specification 3.0.1 — Software Profile, Package class", "organization": "SPDX Project / The Linux Foundation", "url": "https://spdx.github.io/spdx-spec/v3.0.1/model/Software/Classes/Package/", "version_or_date": "3.0.1 (2024-12)", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:05:00Z", "relevance": "Normative property set and cardinality for a software package: packageUrl, packageVersion, downloadLocation, homePage, sourceInfo, contentIdentifier, plus inherited name (1..1), originatedBy, suppliedBy, builtTime, releaseTime, validUntilTime, supportLevel, primaryPurpose, verifiedUsing, externalIdentifier." }, { "id": "SRC-002", "title": "SPDX Specification 3.0.1 — Annex E, Package URL specification", "organization": "SPDX Project / The Linux Foundation", "url": "https://spdx.github.io/spdx-spec/v3.0.1/annexes/pkg-url-specification/", "version_or_date": "3.0.1 (2024-12)", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:07:00Z", "relevance": "Full purl syntax scheme:type/namespace/name@version?qualifiers#subpath with required components (scheme, type, name), normalization and percent-encoding rules, known purl types, and standard qualifiers repository_url, download_url, vcs_url, file_name, checksum." }, { "id": "SRC-003", "title": "Package-URL (purl) — Introduction and ECMA-427 standardization", "organization": "Ecma International / package-url project", "url": "https://www.packageurl.org/docs/purl/introduction", "version_or_date": "ECMA-427 1st edition, approved 2025-12-10, released 2025-12-18", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:10:00Z", "relevance": "Establishes purl as a formally standardized, ecosystem-independent package identifier and states its purpose for supply-chain traceability, vulnerability matching and cross-tool automation." }, { "id": "SRC-004", "title": "Semantic Versioning 2.0.0", "organization": "Semantic Versioning (semver.org)", "url": "https://semver.org/", "version_or_date": "2.0.0", "source_type": "standard", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T09:12:00Z", "relevance": "Normative MAJOR.MINOR.PATCH increment rules, pre-release and build-metadata syntax, precedence rules (build metadata ignored for precedence) and the immutability rule that released version contents MUST NOT be modified." }, { "id": "SRC-005", "title": "CycloneDX v1.6 JSON Reference — component object", "organization": "OWASP Foundation / Ecma TC54", "url": "https://cyclonedx.org/docs/1.6/json/", "version_or_date": "1.6", "source_type": "schema", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:15:00Z", "relevance": "Component field set with required type and name; optional version, supplier, manufacturer, authors, publisher, group, scope (required/optional/excluded), hashes, licenses, cpe, purl, omniborId, swhid, swid, pedigree, evidence, externalReferences, nested components and properties." }, { "id": "SRC-006", "title": "SLSA v1.2 — Build Provenance specification", "organization": "Open Source Security Foundation (OpenSSF) / SLSA", "url": "https://slsa.dev/spec/v1.2/build-provenance", "version_or_date": "v1.2 (Approved)", "source_type": "standard", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T09:18:00Z", "relevance": "Provenance predicate schema: buildDefinition (buildType, externalParameters required; internalParameters, resolvedDependencies optional), runDetails (builder.id required; version, builderDependencies, metadata invocationId/startedOn/finishedOn, byproducts optional), ResourceDescriptor fields and the timestamp format constraint." }, { "id": "SRC-007", "title": "in-toto Attestation Framework — Statement layer v1", "organization": "in-toto project / Cloud Native Computing Foundation", "url": "https://github.com/in-toto/attestation/blob/main/spec/v1/statement.md", "version_or_date": "Statement v1 (main branch)", "source_type": "standard", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T09:20:00Z", "relevance": "Required _type, subject, predicateType and optional predicate; the rule that each subject element MUST set digest, that artifacts are matched exclusively by digest, and that subjects are treated as immutable." }, { "id": "SRC-008", "title": "Open Source Vulnerability (OSV) Schema", "organization": "Open Source Security Foundation (OpenSSF)", "url": "https://ossf.github.io/osv-schema/", "version_or_date": "OSV Schema, current published revision", "source_type": "schema", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T09:23:00Z", "relevance": "Required id, modified and schema_version; published and withdrawn timestamps; affected[].package with ecosystem, name and purl; ranges of type GIT/SEMVER/ECOSYSTEM with introduced/fixed/last_affected/limit events; severity, references, credits; RFC3339 UTC timestamp requirement." }, { "id": "SRC-009", "title": "SPDX Specification 3.0.1 — Annex D, SPDX license expressions", "organization": "SPDX Project / The Linux Foundation", "url": "https://spdx.github.io/spdx-spec/v3.0.1/annexes/spdx-license-expressions/", "version_or_date": "3.0.1 (2024-12)", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:26:00Z", "relevance": "Licence expression grammar: SPDX License List identifiers, LicenseRef and DocumentRef forms, the unary + operator, AND/OR/WITH operators, operator precedence and parenthesization, and case rules for identifiers versus operators." }, { "id": "SRC-010", "title": "Cyber Resilience Act — summary of legal provisions", "organization": "European Commission, Directorate-General for Communications Networks, Content and Technology", "url": "https://digital-strategy.ec.europa.eu/en/policies/cra-summary", "version_or_date": "Regulation (EU) 2024/2847, summary page", "source_type": "legislation", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:30:00Z", "relevance": "Annex I Part II vulnerability-handling duty covering the product 'including its components'; manufacturer-determined support period with an end date specified at purchase; third-party component due diligence; open-source steward duties; 24-hour early warning, 72-hour notification and 14-day final report timelines." }, { "id": "SRC-011", "title": "NIST IR 7695 — Common Platform Enumeration: Naming Specification Version 2.3", "organization": "National Institute of Standards and Technology (NIST)", "url": "https://csrc.nist.gov/pubs/ir/7695/final", "version_or_date": "Version 2.3, August 2011", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:33:00Z", "relevance": "Defines the logical structure for naming classes of IT products and the conversion of those names to and from machine-readable bindings, establishing CPE as a product-class identifier distinct from an artifact identifier." }, { "id": "SRC-012", "title": "NIST IR 8060 — Guidelines for the Creation of Interoperable Software Identification (SWID) Tags", "organization": "National Institute of Standards and Technology (NIST)", "url": "https://csrc.nist.gov/pubs/ir/8060/final", "version_or_date": "April 2016", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:35:00Z", "relevance": "Places ISO/IEC 19770-2 SWID tags in the software lifecycle for software asset management and information security management, supporting the boundary between installed-asset identity and package identity." }, { "id": "SRC-013", "title": "OCI Image Format Specification — Content Descriptors", "organization": "Open Container Initiative", "url": "https://github.com/opencontainers/image-spec/blob/main/descriptor.md", "version_or_date": "Image Spec v1 (descriptor media type application/vnd.oci.descriptor.v1+json)", "source_type": "standard", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T09:38:00Z", "relevance": "Required mediaType, digest and size; optional urls, annotations, data, artifactType; digest format algorithm:encoded; the statement that digest acts as a content identifier enabling content addressability and that bytes from untrusted sources SHOULD be verified against it." }, { "id": "SRC-014", "title": "PEP 592 — Adding \"Yank\" Support to the Simple API", "organization": "Python Software Foundation / Python Packaging Authority", "url": "https://peps.python.org/pep-0592/", "version_or_date": "Final, created 2019-05-07", "source_type": "standard", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T09:41:00Z", "relevance": "Defines yanking as a non-destructive lifecycle state: installers MUST ignore yanked releases when constraints can be satisfied otherwise, yanked files remain installable when explicitly pinned or lock-file selected, and an optional yank reason string may be surfaced." }, { "id": "SRC-015", "title": "npm Unpublish Policy", "organization": "npm, Inc. / GitHub", "url": "https://docs.npmjs.com/policies/unpublish", "version_or_date": "Current published policy", "source_type": "first-party-doc", "primary_source": true, "authority_tier": 3, "accessed_at": "2026-08-26T09:44:00Z", "relevance": "Registry-of-record deletion regime: 72-hour unrestricted unpublish window, post-window conditions (no dependents, low download count, single maintainer), the rule that a package@version once used can never be reused, a 24-hour name cooldown, and deprecation as the recommended alternative." }, { "id": "SRC-016", "title": "OpenSSF Scorecard — Checks documentation", "organization": "Open Source Security Foundation (OpenSSF)", "url": "https://github.com/ossf/scorecard/blob/main/docs/checks.md", "version_or_date": "Current published checks documentation", "source_type": "first-party-doc", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T09:47:00Z", "relevance": "Enumerated project-health and security-practice checks with risk levels (Dangerous-Workflow and Webhooks critical; Branch-Protection, Code-Review, Maintained, Signed-Releases, Vulnerabilities high) and the 0-10 tiered scoring model used to produce comparable adoption signals." }, { "id": "SRC-017", "title": "NIST SP 800-218 — Secure Software Development Framework (SSDF) Version 1.1", "organization": "National Institute of Standards and Technology (NIST)", "url": "https://csrc.nist.gov/pubs/sp/800/218/final", "version_or_date": "Version 1.1, February 2022", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:50:00Z", "relevance": "High-level secure development practices integrable into any SDLC, providing the process framing for release integrity verification, archiving and protecting releases with provenance data, and reuse of well-secured third-party software." }, { "id": "SRC-018", "title": "SPDX Specification 3.0.1 — Software Profile overview", "organization": "SPDX Project / The Linux Foundation", "url": "https://spdx.github.io/spdx-spec/v3.0.1/model/Software/Software/", "version_or_date": "3.0.1 (2024-12)", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:52:00Z", "relevance": "Profile inventory distinguishing Package, File, Snippet, SoftwareArtifact and Sbom classes, and the ContentIdentifierType, FileKindType, SbomType and SoftwarePurpose vocabularies used for classification and for the boundary to the SBOM model." }, { "id": "SRC-019", "title": "Cyber Resilience Act — policy page", "organization": "European Commission, Directorate-General for Communications Networks, Content and Technology", "url": "https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act", "version_or_date": "Regulation (EU) 2024/2847; in force 2024-12-10; reporting obligations from 2026-09-11; general application from 2027-12-11", "source_type": "public-authority", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T09:54:00Z", "relevance": "Authoritative dates for entry into force, the start of reporting obligations and general application, plus CE marking and market-surveillance enforcement context for components placed on the EU market." }, { "id": "SRC-020", "title": "ExternalIdentifierType - SPDX Specification 3.0.1", "organization": "Linux Foundation SPDX Project", "url": "https://spdx.github.io/spdx-spec/v3.0.1/model/Core/Vocabularies/ExternalIdentifierType/", "version_or_date": "SPDX Specification 3.0.1", "source_type": "schema", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Enumerates package-url, cpe22, cpe23, swhid, gitoid and other external identifier types used on software artifacts." }, { "id": "SRC-021", "title": "RelationshipType - SPDX Specification 3.0.1", "organization": "Linux Foundation SPDX Project", "url": "https://spdx.github.io/spdx-spec/v3.0.1/model/Core/Vocabularies/RelationshipType/", "version_or_date": "SPDX Specification 3.0.1", "source_type": "schema", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Typed edges for dependsOn, contains, hasOptionalDependency, hasProvidedDependency, hasStaticLink, hasDynamicLink, hasDeclaredLicense, hasConcludedLicense, packagedBy, patchedBy and related package graph relations." }, { "id": "SRC-022", "title": "Hash - SPDX Specification 3.0.1", "organization": "Linux Foundation SPDX Project", "url": "https://spdx.github.io/spdx-spec/v3.0.1/model/Core/Classes/Hash/", "version_or_date": "SPDX Specification 3.0.1", "source_type": "schema", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "IntegrityMethod subclass requiring algorithm and hashValue for package verification." }, { "id": "SRC-023", "title": "SoftwarePurpose - SPDX Specification 3.0.1", "organization": "Linux Foundation SPDX Project", "url": "https://spdx.github.io/spdx-spec/v3.0.1/model/Software/Vocabularies/SoftwarePurpose/", "version_or_date": "SPDX Specification 3.0.1", "source_type": "classifier", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Vocabulary for primaryPurpose and additionalPurpose of a package, including library, application, container, source, install, patch and archive." }, { "id": "SRC-024", "title": "Standard ECMA-427 Package-URL (PURL) specification, 1st Edition", "organization": "Ecma International Technical Committee 54", "url": "https://ecma-tc54.github.io/ECMA-427/multipage/", "version_or_date": "1st Edition / December 2025", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "International standard for the Package-URL syntax that uniquely identifies software packages independent of ecosystem or channel." }, { "id": "SRC-025", "title": "Common Platform Enumeration: Naming Specification Version 2.3 (NISTIR 7695)", "organization": "National Institute of Standards and Technology", "url": "https://csrc.nist.gov/projects/security-content-automation-protocol/specifications/cpe-2-3", "version_or_date": "NISTIR 7695 / August 2011", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "CPE 2.3 well-formed names identify abstract classes of applications, operating systems and hardware, not unique installed instantiations." }, { "id": "SRC-026", "title": "Guidelines for the Creation of Interoperable Software Identification (SWID) Tags (NISTIR 8060) and ISO/IEC 19770-2", "organization": "National Institute of Standards and Technology", "url": "https://csrc.nist.gov/projects/software-identification-swid/guidelines", "version_or_date": "NISTIR 8060 April 2016; ISO/IEC 19770-2:2015", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "SWID tags identify software products, versions, producing organizations, constituent artifacts and relationships, with corpus, primary, patch and supplemental lifecycle roles." }, { "id": "SRC-027", "title": "SWHID: International Standard for Software Artifact Identification (ISO/IEC 18670:2025)", "organization": "ISO/IEC JTC 1 / SWHID Working Group", "url": "https://swhid.org/", "version_or_date": "ISO/IEC 18670:2025 (adopted 2025-04-23)", "source_type": "standard", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Persistent intrinsic identifiers for software artifacts computed from content via Merkle DAGs, independently verifiable without a central registry." }, { "id": "SRC-028", "title": "Semantic Versioning 2.0.0", "organization": "Semantic Versioning (semver.org)", "url": "https://semver.org/spec/v2.0.0.html", "version_or_date": "2.0.0", "source_type": "first-party-doc", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Rules for MAJOR.MINOR.PATCH, pre-release and build metadata, precedence, and the requirement that a released version's contents MUST NOT be modified." }, { "id": "SRC-029", "title": "POM Reference – Maven", "organization": "Apache Software Foundation", "url": "https://maven.apache.org/pom.html", "version_or_date": "Maven POM modelVersion 4.0.0 (page accessed 2026-08-26)", "source_type": "first-party-doc", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Authoritative Maven coordinates groupId:artifactId:version, packaging, classifier, dependency scopes and repository layout for Java ecosystem packages." }, { "id": "SRC-030", "title": "2026 Minimum Elements for a Software Bill of Materials (SBOM)", "organization": "Cybersecurity and Infrastructure Security Agency", "url": "https://www.cisa.gov/resources-tools/resources/2026-minimum-elements-software-bill-materials-sbom", "version_or_date": "2026-07-29", "source_type": "public-authority", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Current US and partner public-authority guidance replacing the 2021 NTIA SBOM minimum elements; treats component identity and supply-chain transparency as baseline practice." }, { "id": "SRC-031", "title": "Framing Software Component Transparency (2024)", "organization": "Cybersecurity and Infrastructure Security Agency", "url": "https://www.cisa.gov/resources-tools/resources/framing-software-component-transparency-2024", "version_or_date": "2024-10-15 (third edition)", "source_type": "public-authority", "primary_source": true, "authority_tier": 2, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Defines SBOM attributes for uniquely identifying software components and their relationships, with minimum, recommended and aspirational levels." }, { "id": "SRC-032", "title": "SoftwareArtifact - SPDX Specification 3.0.1", "organization": "Linux Foundation SPDX Project", "url": "https://spdx.github.io/spdx-spec/v3.0.1/model/Software/Classes/SoftwareArtifact/", "version_or_date": "SPDX Specification 3.0.1", "source_type": "schema", "primary_source": true, "authority_tier": 1, "accessed_at": "2026-08-26T16:30:00Z", "relevance": "Abstract parent of Package: contentIdentifier, copyrightText, primaryPurpose, originatedBy, suppliedBy, supportLevel, validUntilTime, builtTime, releaseTime and verifiedUsing." } ], "structure": { "bundles": [ { "id": "b-identity-and-version", "name": "Identity, Naming and Version Designation", "description": "How a component is uniquely named, how its release is designated and how its bytes are addressed and verified.", "rationale": "Every downstream operation (dependency resolution, vulnerability matching, licence attribution, provenance verification) fails silently without a stable, normalizable identity and a defensible version designation. purl, CPE, SWID and content digests each solve a different identity problem and must be modelled separately rather than collapsed.", "source_refs": [ "SRC-002", "SRC-003", "SRC-001", "SRC-004", "SRC-013", "SRC-011", "SRC-012", "SRC-005" ], "layers": [ { "id": "l-package-coordinates", "name": "Package Coordinates and Identifier Alignment", "description": "Ecosystem coordinates, cross-scheme identifiers and content-address integrity for the component and its artifacts.", "source_refs": [ "SRC-002", "SRC-003", "SRC-011", "SRC-012", "SRC-013", "SRC-005" ], "findings": [ { "id": "f-ecosystem-coordinate", "name": "Ecosystem coordinate identity", "description": "The purl type, optional namespace and name that address the component in its ecosystem of record, plus the normalization rules that must run before any comparison.", "source_refs": [ "SRC-002", "SRC-003", "SRC-005" ], "questions": [ { "id": "q-coordinate-address", "text": "Which purl type, namespace and name uniquely address this component in its ecosystem of record?", "kind": "identity", "answer_data": [ "purl type token", "namespace segments (decoded)", "name", "canonical purl string" ] }, { "id": "q-coordinate-project-vs-release", "text": "What distinguishes the project-level identity of this component from the identity of one specific release?", "kind": "definition", "answer_data": [ "versionless purl for the project", "versioned purl for the release", "statement of which operations bind to which level" ] }, { "id": "q-coordinate-normalization", "text": "Which normalization rules must be applied to the coordinate before two identities are treated as equal?", "kind": "constraint", "answer_data": [ "type lowercasing rule", "type-specific case rule for namespace and name", "percent-encoding decisions", "qualifier ordering and empty-value removal" ] }, { "id": "q-coordinate-authority", "text": "Which registry or namespace authority allocates this name, and may the name be reassigned after removal?", "kind": "authority", "answer_data": [ "namespace authority identifier", "name-reuse policy reference", "cooldown or permanent-reservation flag" ] } ], "data_elements": [ { "id": "de-purl-canonical", "name": "Canonical purl", "description": "Normalized Package URL string for the component, versionless at project level and versioned at release level.", "value_kind": "identifier", "cardinality": "1", "required": true, "source_refs": [ "SRC-002", "SRC-003" ] }, { "id": "de-package-type", "name": "Package type", "description": "purl type token identifying the ecosystem or packaging convention, lowercase ASCII and never starting with a digit.", "value_kind": "code", "cardinality": "1", "required": true, "source_refs": [ "SRC-002" ] }, { "id": "de-package-namespace", "name": "Package namespace", "description": "Type-specific grouping prefix such as a Maven groupId, npm scope or Go module path prefix.", "value_kind": "text", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-002", "SRC-005" ] }, { "id": "de-package-name", "name": "Package name", "description": "Registry-native name of the component within its type and namespace.", "value_kind": "text", "cardinality": "1", "required": true, "source_refs": [ "SRC-002", "SRC-001" ] } ], "artifacts": [ { "id": "a-registry-metadata-record", "name": "Registry metadata record", "description": "The registry-of-record document describing the package coordinates, canonical name and available releases, retrieved and stored as retrieved.", "media_or_form": [ "registry metadata document", "canonical purl string", "registry API response snapshot" ], "serial": false, "identity_strategy": "Registry-of-record package key as the authoritative master-system identifier; canonical purl as the governed global identifier; snapshot digest for the stored copy.", "source_refs": [ "SRC-002", "SRC-003", "SRC-001" ] } ], "inline_only_rationale": null }, { "id": "f-cross-scheme-identifiers", "name": "Cross-scheme identifier alignment", "description": "Additional identifier schemes asserted for the component (CPE, SWID, content identifiers such as SWHID or OmniBOR) and the confidence and directionality of each mapping.", "source_refs": [ "SRC-011", "SRC-012", "SRC-005", "SRC-001", "SRC-018" ], "questions": [ { "id": "q-crossid-schemes", "text": "Which additional identifier schemes are asserted for this component, and by which asserting party?", "kind": "interoperability", "answer_data": [ "CPE names", "SWID tag identifiers", "content identifiers such as SWHID or OmniBOR", "external identifier type and value pairs", "asserting agent per identifier" ] }, { "id": "q-crossid-evidence", "text": "What evidence supports each cross-scheme mapping, and is it one-to-one, many-to-one or unverified?", "kind": "validation", "answer_data": [ "mapping evidence reference", "cardinality class of the mapping", "verification status and verifier" ] }, { "id": "q-crossid-false-match", "text": "How is a conflicting or over-broad identifier match handled when it produces false vulnerability hits?", "kind": "exception", "answer_data": [ "suppression record", "suppression scope and justification", "review date and approving agent" ] }, { "id": "q-crossid-authoritative-use", "text": "Which identifier scheme is authoritative for which downstream use case?", "kind": "classification", "answer_data": [ "use case to scheme mapping", "precedence rule", "documented exclusions" ] } ], "data_elements": [ { "id": "de-cpe-name", "name": "CPE name", "description": "Common Platform Enumeration name asserted for the product class corresponding to this component.", "value_kind": "identifier", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-011", "SRC-005" ] }, { "id": "de-swid-tag-id", "name": "SWID tag identifier", "description": "ISO/IEC 19770-2 software identification tag identifier associated with the installed form of this component.", "value_kind": "identifier", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-012", "SRC-005" ] }, { "id": "de-content-identifier", "name": "Content identifier", "description": "Content-derived identifier such as a Software Heritage identifier or OmniBOR artifact identifier.", "value_kind": "identifier", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-018", "SRC-005" ] }, { "id": "de-mapping-confidence", "name": "Identifier mapping confidence", "description": "Recorded confidence class for a cross-scheme identifier assertion.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-005" ] } ], "artifacts": [ { "id": "a-identifier-crosswalk", "name": "Identifier crosswalk record", "description": "Stored mapping between the canonical purl and each asserted external identifier, with evidence, confidence and asserting agent.", "media_or_form": [ "crosswalk table", "external identifier list", "suppression list" ], "serial": false, "identity_strategy": "Composite of canonical purl plus target scheme and target value; Dimension-assigned ULID only where the pair is not itself unique.", "source_refs": [ "SRC-011", "SRC-012", "SRC-005" ] } ], "inline_only_rationale": null }, { "id": "f-content-address-integrity", "name": "Content address and integrity verification", "description": "Cryptographic digests over the exact released byte streams, the algorithms accepted, and the mandatory verification step before consumption.", "source_refs": [ "SRC-013", "SRC-007", "SRC-002", "SRC-005", "SRC-001", "SRC-017" ], "questions": [ { "id": "q-digest-coverage", "text": "Which cryptographic digests, computed over which exact byte streams, address the released artifacts?", "kind": "identity", "answer_data": [ "digest algorithm and encoded value pairs", "byte stream each digest covers", "artifact size in bytes", "media type" ] }, { "id": "q-digest-verification-procedure", "text": "What verification procedure is required before these bytes are consumed from an untrusted source?", "kind": "validation", "answer_data": [ "verification procedure reference", "verification outcome", "verification timestamp", "actor or tool performing verification" ] }, { "id": "q-digest-algorithm-policy", "text": "Which digest algorithms are accepted for this ecosystem and which are deprecated or forbidden?", "kind": "security", "answer_data": [ "accepted algorithm list", "deprecated algorithm list", "policy reference and effective date" ] }, { "id": "q-digest-versus-tag", "text": "How does an immutable artifact digest relate to the mutable registry tag or channel that pointed to it?", "kind": "relationship", "answer_data": [ "tag or channel name", "digest resolved from the tag", "resolution timestamp", "tag mutability flag" ] } ], "data_elements": [ { "id": "de-artifact-digest", "name": "Artifact digest", "description": "Digest of a released artifact in algorithm:encoded form, acting as the content identifier and comparison key.", "value_kind": "identifier", "cardinality": "1..n", "required": true, "source_refs": [ "SRC-013", "SRC-007", "SRC-005" ] }, { "id": "de-artifact-size", "name": "Artifact size", "description": "Size in bytes of the raw content addressed by the digest.", "value_kind": "quantity", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-013" ] }, { "id": "de-verification-outcome", "name": "Integrity verification outcome", "description": "Result of verifying retrieved bytes against the recorded digest, together with the verifying actor.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-013", "SRC-017" ] }, { "id": "de-verified-at", "name": "Verification time", "description": "Observation time at which integrity verification was executed.", "value_kind": "timestamp", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-013", "SRC-008" ] } ], "artifacts": [ { "id": "a-content-descriptor-set", "name": "Content descriptor set", "description": "Set of descriptors for the released bytes carrying media type, digest and size, in the form used by the distribution channel.", "media_or_form": [ "content descriptor document", "checksum manifest", "registry integrity metadata" ], "serial": false, "identity_strategy": "Digest in algorithm:encoded form is the primary artifact identity; no Dimension-assigned identifier is required.", "source_refs": [ "SRC-013", "SRC-002" ] } ], "inline_only_rationale": null } ] }, { "id": "l-version-designation", "name": "Version Designation and Release Composition", "description": "The version scheme that orders releases and the set of distribution artifacts that constitute one release.", "source_refs": [ "SRC-004", "SRC-001", "SRC-002", "SRC-005", "SRC-018" ], "findings": [ { "id": "f-version-scheme", "name": "Version scheme, precedence and immutability", "description": "Which versioning scheme governs the version string, how two versions are ordered, and whether published content for a version is immutable.", "source_refs": [ "SRC-004", "SRC-001", "SRC-002", "SRC-008", "SRC-015" ], "questions": [ { "id": "q-version-scheme-declared", "text": "Which versioning scheme governs this component's version strings, and was that scheme declared or inferred?", "kind": "classification", "answer_data": [ "version scheme identifier", "declared or inferred flag", "evidence for inference" ] }, { "id": "q-version-ordering", "text": "How are two versions of this component ordered, and how are pre-release and build metadata treated in that ordering?", "kind": "constraint", "answer_data": [ "precedence function reference", "pre-release ordering rule", "build-metadata handling rule", "computed precedence key" ] }, { "id": "q-version-immutability", "text": "Is the published content for a given version immutable, and what mechanism enforces that?", "kind": "requirement", "answer_data": [ "immutability rule reference", "enforcement mechanism", "known exceptions and their scope" ] }, { "id": "q-version-cross-scheme-exchange", "text": "How is this version string represented when exchanged with a tool that assumes a different version scheme?", "kind": "interoperability", "answer_data": [ "target scheme", "translated representation", "lossiness note", "fallback to opaque string" ] } ], "data_elements": [ { "id": "de-version-string", "name": "Version string", "description": "Opaque version token as published by the registry of record, stored verbatim before any interpretation.", "value_kind": "text", "cardinality": "1", "required": true, "source_refs": [ "SRC-002", "SRC-001" ] }, { "id": "de-version-scheme", "name": "Version scheme", "description": "Identifier of the ordering scheme that applies to the version string, such as a semantic, ecosystem-specific or opaque scheme.", "value_kind": "code", "cardinality": "1", "required": true, "source_refs": [ "SRC-004", "SRC-008" ] }, { "id": "de-version-precedence-key", "name": "Version precedence key", "description": "Derived sortable key computed by the declared scheme's precedence function, never used as an identifier.", "value_kind": "text", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-004" ] }, { "id": "de-prerelease-flag", "name": "Pre-release indicator", "description": "Whether the version designates a pre-release that ranks below the corresponding normal version.", "value_kind": "boolean", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-004" ] } ], "artifacts": [ { "id": "a-release-index", "name": "Release index", "description": "Published list of releases for the component with their version strings and publication state, as retrieved from the registry of record.", "media_or_form": [ "release index document", "registry version listing" ], "serial": false, "identity_strategy": "Versionless canonical purl plus registry-of-record endpoint; snapshot digest and observation time distinguish successive retrievals.", "source_refs": [ "SRC-002", "SRC-015" ] } ], "inline_only_rationale": null }, { "id": "f-release-variant-set", "name": "Release variant and distribution set", "description": "The distinct distribution artifacts that constitute one release (source distribution, binaries, platform and architecture variants) and how a consumer selects among them.", "source_refs": [ "SRC-002", "SRC-005", "SRC-018", "SRC-013", "SRC-001" ], "questions": [ { "id": "q-variant-membership", "text": "Which distinct distribution artifacts make up this release, and are any of them optional?", "kind": "composition", "answer_data": [ "artifact list with file names", "source versus built artifact flag", "optionality per artifact" ] }, { "id": "q-variant-purpose", "text": "What is the primary purpose and packaging form of each artifact in the release?", "kind": "classification", "answer_data": [ "primary purpose term", "additional purpose terms", "packaging form or media type" ] }, { "id": "q-variant-selection", "text": "Which artifact must be selected for a given target platform, and which metadata drives that selection?", "kind": "decision", "answer_data": [ "target platform expression", "architecture and operating system qualifiers", "selection rule reference" ] }, { "id": "q-variant-identity", "text": "Does each variant carry its own identifier and digest, or do all variants share the release identity?", "kind": "identity", "answer_data": [ "per-variant purl qualifiers", "per-variant digest", "shared release identifier" ] } ], "data_elements": [ { "id": "de-distribution-artifact", "name": "Distribution artifact", "description": "One downloadable file belonging to the release, with file name, media type, digest and qualifiers.", "value_kind": "collection", "cardinality": "1..n", "required": true, "source_refs": [ "SRC-002", "SRC-013" ] }, { "id": "de-target-platform", "name": "Target platform qualifier", "description": "Operating system, architecture or runtime qualifier constraining where an artifact is usable.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-002", "SRC-005" ] }, { "id": "de-primary-purpose", "name": "Primary purpose", "description": "Classification of what the artifact is, such as library, application, container, firmware, source or data.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-001", "SRC-018", "SRC-005" ] } ], "artifacts": [ { "id": "a-release-artifact-file", "name": "Release artifact file", "description": "An individual distributable file of the release, retained with its descriptor and qualifiers.", "media_or_form": [ "archive file", "binary package", "source distribution", "container image layer set" ], "serial": true, "identity_strategy": "Content digest as primary identity; canonical purl with distinguishing qualifiers as the governed global identifier; sequence number only for ordering within the release set.", "source_refs": [ "SRC-002", "SRC-013", "SRC-005" ] } ], "inline_only_rationale": null }, { "id": "f-component-type-purpose", "name": "Component type and software purpose", "description": "CycloneDX requires a component type such as application, library, framework, container, operating-system, firmware, file or machine-learning-model. SPDX records primaryPurpose and additionalPurpose, noting that purpose is intrinsic to how the element is used rather than solely to its content. The two vocabularies overlap but are not identical.", "source_refs": [ "SRC-001", "SRC-023", "SRC-005" ], "questions": [ { "id": "f-component-type-purpose-q01", "text": "What CycloneDX component type classifies this package?", "kind": "classification", "answer_data": [ "CycloneDX type code", "Fallback rule if classified as application because no more specific type applies" ] }, { "id": "f-component-type-purpose-q02", "text": "What SPDX primaryPurpose and additionalPurpose values describe how this package is used?", "kind": "classification", "answer_data": [ "primaryPurpose code", "additionalPurpose codes", "Producer versus consumer usage notes" ] }, { "id": "f-component-type-purpose-q03", "text": "Is the recorded purpose based on use context rather than bit content, and could the same bits be a library in one product and an application in another?", "kind": "definition", "answer_data": [ "Boolean use-context flag", "Alternate purpose in another composition", "Rationale" ] } ], "data_elements": [ { "id": "f-component-type-purpose-data01", "name": "CycloneDX component type", "description": "Required type in CycloneDX component records.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-005" ] }, { "id": "f-component-type-purpose-data02", "name": "SPDX primary purpose", "description": "Primary SoftwarePurpose of the package.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-023", "SRC-032" ] }, { "id": "f-component-type-purpose-data03", "name": "SPDX additional purposes", "description": "Additional SoftwarePurpose values.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-023" ] } ], "artifacts": [], "inline_only_rationale": "Type and purpose are classifier codes on the package record. They are not independent artifacts." } ] } ] }, { "id": "b-composition", "name": "Composition, Dependencies and Derivation", "description": "What the component declares it needs, what a resolver actually selected, what the artifact contains, and what it was derived from.", "rationale": "Dependency relationship is a minimum element of every component inventory practice, and the declared constraint, the resolved selection and the bundled content are three different facts that are routinely conflated. Pedigree is separately modelled by CycloneDX because modification and repackaging change licence and provenance conclusions.", "source_refs": [ "SRC-005", "SRC-006", "SRC-001", "SRC-018", "SRC-002", "SRC-017" ], "layers": [ { "id": "l-dependency-relations", "name": "Declared and Resolved Dependencies", "description": "Dependency constraints declared by the component and the concrete closure a resolver produced from them.", "source_refs": [ "SRC-005", "SRC-006", "SRC-001", "SRC-002" ], "findings": [ { "id": "f-declared-dependencies", "name": "Declared dependency constraints", "description": "The dependency edges the component itself declares, with version constraint expressions, scope and linkage kind.", "source_refs": [ "SRC-005", "SRC-001", "SRC-002", "SRC-018" ], "questions": [ { "id": "q-dep-declared-set", "text": "Which dependencies does this component declare, and under which version constraint expression for each?", "kind": "relationship", "answer_data": [ "target component coordinate", "constraint expression as written", "constraint scheme" ] }, { "id": "q-dep-scope", "text": "What is the scope of each declared dependency, and does it reach the distributed artifact at all?", "kind": "classification", "answer_data": [ "scope term such as required, optional or excluded", "build, test or development classification", "reaches-distribution flag" ] }, { "id": "q-dep-conditionality", "text": "Which declared dependencies are conditional on platform, feature flag or optional extra?", "kind": "constraint", "answer_data": [ "condition expression", "condition kind", "default activation state" ] }, { "id": "q-dep-linkage", "text": "Is the dependency linked statically, dynamically or used only as a tool, and does that change obligations?", "kind": "composition", "answer_data": [ "linkage kind", "obligation delta note", "evidence for the linkage determination" ] } ], "data_elements": [ { "id": "de-dependency-edge", "name": "Declared dependency edge", "description": "One declared relationship from this component to a target coordinate, with its constraint and scope.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005", "SRC-001" ] }, { "id": "de-version-constraint", "name": "Version constraint expression", "description": "The version range or pin as declared, retained verbatim alongside its interpretation scheme.", "value_kind": "text", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-008", "SRC-005" ] }, { "id": "de-dependency-scope", "name": "Dependency scope", "description": "Scope classification of the dependency, such as required, optional or excluded.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005" ] }, { "id": "de-linkage-kind", "name": "Linkage kind", "description": "How the dependency is bound at build or run time: static, dynamic or tool-only.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005" ] } ], "artifacts": [ { "id": "a-dependency-manifest", "name": "Dependency manifest", "description": "The component's own declaration of dependencies as published in the release, retained verbatim.", "media_or_form": [ "package manifest", "module descriptor", "build configuration file" ], "serial": false, "identity_strategy": "Versioned canonical purl of the declaring release plus manifest path; content digest for the retained copy.", "source_refs": [ "SRC-005", "SRC-002" ] } ], "inline_only_rationale": null }, { "id": "f-resolved-closure", "name": "Resolved dependency closure", "description": "The concrete transitive set a resolver selected at a stated instant, together with the completeness of that closure.", "source_refs": [ "SRC-006", "SRC-005", "SRC-002", "SRC-017" ], "questions": [ { "id": "q-closure-resolver", "text": "Which resolver, resolver version and registry state produced this closure?", "kind": "process", "answer_data": [ "resolver identifier and version", "registry endpoints consulted", "resolver configuration reference" ] }, { "id": "q-closure-instant", "text": "At which instant was the closure resolved, and can it be reproduced from the recorded inputs?", "kind": "temporal", "answer_data": [ "resolution timestamp", "reproducibility flag", "recorded input set" ] }, { "id": "q-closure-membership", "text": "What is the complete transitive component set, and which members are direct rather than transitive?", "kind": "composition", "answer_data": [ "resolved component coordinates with digests", "direct or transitive flag", "depth from the root" ] }, { "id": "q-closure-completeness", "text": "How complete is the recorded closure, and which parts are explicitly declared unknown?", "kind": "quality", "answer_data": [ "completeness class", "known-unknown entries with reasons", "coverage note" ] } ], "data_elements": [ { "id": "de-resolved-component", "name": "Resolved component reference", "description": "A concrete component release selected by the resolver, identified by versioned purl and where available by digest.", "value_kind": "reference", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-006", "SRC-002" ] }, { "id": "de-resolution-timestamp", "name": "Resolution timestamp", "description": "Event time at which the resolver produced the closure.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006" ] }, { "id": "de-closure-completeness", "name": "Closure completeness", "description": "Declared completeness of the closure, including whether unknown areas are asserted rather than silently omitted.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006", "SRC-005" ] } ], "artifacts": [ { "id": "a-resolved-closure-record", "name": "Resolved closure record", "description": "The lock or resolution output enumerating every selected component release with its pinned version and integrity value.", "media_or_form": [ "lock file", "resolved dependency list", "resolvedDependencies descriptor array" ], "serial": false, "identity_strategy": "Digest of the resolution output plus the root component's versioned purl and the resolution event time.", "source_refs": [ "SRC-006", "SRC-005" ] } ], "inline_only_rationale": null } ] }, { "id": "l-internal-composition", "name": "Contained Content and Derivation", "description": "What the released artifact actually contains, including undeclared bundled code, and what upstream work it was derived from.", "source_refs": [ "SRC-001", "SRC-018", "SRC-005", "SRC-002" ], "findings": [ { "id": "f-contained-contents", "name": "Contained files, snippets and bundled subcomponents", "description": "Files and subpaths inside the released artifact, and third-party code bundled or vendored without a manifest declaration.", "source_refs": [ "SRC-001", "SRC-018", "SRC-005", "SRC-002" ], "questions": [ { "id": "q-contents-inventory", "text": "Which files or subpaths does the released artifact contain, and which of them are third-party code?", "kind": "composition", "answer_data": [ "file inventory with kinds", "content identifiers per file", "third-party flag with attributed origin" ] }, { "id": "q-contents-undeclared-evidence", "text": "What evidence identifies bundled code that is not declared in the dependency manifest?", "kind": "evidence", "answer_data": [ "detection technique", "matched content identifier or snippet range", "detecting tool and version" ] }, { "id": "q-contents-subpath-use", "text": "Which contained subpath is referenced when only part of the component is used?", "kind": "constraint", "answer_data": [ "normalized subpath", "purl with subpath fragment", "reason the partial reference is needed" ] }, { "id": "q-contents-inheritance", "text": "How do contained subcomponents inherit or override the parent component's licence and provenance?", "kind": "relationship", "answer_data": [ "inheritance rule applied", "overriding licence expression per subcomponent", "provenance attribution per subcomponent" ] } ], "data_elements": [ { "id": "de-contained-file", "name": "Contained file entry", "description": "One file inside the artifact with its kind, path and content identifier.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-018" ] }, { "id": "de-bundled-subcomponent", "name": "Bundled subcomponent", "description": "A nested component detected inside the artifact that is not a declared dependency.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005" ] }, { "id": "de-subpath", "name": "Normalized subpath", "description": "Relative path within the package, normalized by stripping leading and trailing separators and dot segments.", "value_kind": "text", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-002" ] } ], "artifacts": [ { "id": "a-file-inventory", "name": "File inventory with content identifiers", "description": "Enumeration of files and snippets inside the artifact with per-file content identifiers used for bundled-code detection.", "media_or_form": [ "file inventory listing", "snippet range record", "content identifier index" ], "serial": false, "identity_strategy": "Parent artifact digest plus normalized file path; per-file content identifier as the governed identity for matching.", "source_refs": [ "SRC-001", "SRC-018" ] } ], "inline_only_rationale": null }, { "id": "f-pedigree-derivation", "name": "Pedigree, patches and derivation", "description": "Ancestry of the component: what it was derived from, what modifications were applied, and how confident that chain is.", "source_refs": [ "SRC-005", "SRC-001", "SRC-006" ], "questions": [ { "id": "q-pedigree-ancestor", "text": "From which ancestor component, upstream release or revision was this component derived?", "kind": "provenance", "answer_data": [ "ancestor coordinate or revision identifier", "ancestor digest where known", "relationship direction" ] }, { "id": "q-pedigree-modifications", "text": "Which patches, commits or variant changes were applied to the ancestor to produce this component?", "kind": "composition", "answer_data": [ "patch or commit list", "change description per item", "diff or patch artifact reference" ] }, { "id": "q-pedigree-kind", "text": "Is this component a fork, a rebuild, a repackaging or an unmodified redistribution?", "kind": "classification", "answer_data": [ "derivation kind term", "justification", "identity of the repackaging party" ] }, { "id": "q-pedigree-confidence", "text": "What confidence attaches to the pedigree chain, and what evidence supports it?", "kind": "validation", "answer_data": [ "confidence class", "evidence references", "unverified links flagged" ] } ], "data_elements": [ { "id": "de-ancestor-ref", "name": "Ancestor reference", "description": "Reference to the component or revision this component was derived from.", "value_kind": "reference", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005" ] }, { "id": "de-applied-patch", "name": "Applied modification", "description": "A patch, commit or configuration change applied on top of the ancestor.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005", "SRC-006" ] }, { "id": "de-derivation-kind", "name": "Derivation kind", "description": "Classification of how this component relates to its ancestor, such as fork, rebuild, repackage or verbatim redistribution.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-005" ] } ], "artifacts": [ { "id": "a-pedigree-record", "name": "Pedigree record", "description": "Structured record of ancestors, descendants, variants and applied modifications with per-link confidence.", "media_or_form": [ "pedigree structure", "patch set", "derivation note" ], "serial": false, "identity_strategy": "Versioned canonical purl of the derived component; each link identified by ancestor identifier plus modification digest.", "source_refs": [ "SRC-005" ] } ], "inline_only_rationale": null } ] } ] }, { "id": "b-provenance-and-trust", "name": "Origin, Build Provenance and Trust", "description": "Who produced and supplied the component, from which source, through which build, and what makes that claim verifiable.", "rationale": "Supplier identity is a minimum element of component disclosure, but supplier assertion alone is not evidence. SLSA provenance and in-toto attestations give a verifiable link from a subject digest back to a builder and build definition; treating self-declared metadata and verified attestation as the same fact is the most common supply-chain modelling error.", "source_refs": [ "SRC-006", "SRC-007", "SRC-001", "SRC-005", "SRC-017", "SRC-010" ], "layers": [ { "id": "l-origin-roles", "name": "Origin, Roles and Source Linkage", "description": "Which agents played which supply role, and which source revision corresponds to the release.", "source_refs": [ "SRC-001", "SRC-005", "SRC-002", "SRC-010" ], "findings": [ { "id": "f-supply-roles", "name": "Supplier, author and distributor roles", "description": "The distinct agents who originated, supplied and distributed the release, and which of those is accountable for security response.", "source_refs": [ "SRC-001", "SRC-005", "SRC-010" ], "questions": [ { "id": "q-roles-assignment", "text": "Which agent originated, which supplied and which distributed this component release?", "kind": "ownership", "answer_data": [ "originating agent reference", "supplying agent reference", "distributing or publishing agent reference" ] }, { "id": "q-roles-security-authority", "text": "Which role holder is authoritative for security contact and vulnerability response for this component?", "kind": "authority", "answer_data": [ "responsible agent reference", "security contact channel", "stewardship classification" ] }, { "id": "q-roles-assertion-basis", "text": "How was each role assertion obtained, and is it self-declared or independently verified?", "kind": "provenance", "answer_data": [ "assertion basis code", "verifying party where applicable", "source document reference" ] }, { "id": "q-roles-repackager-effect", "text": "How does a repackager, mirror or internal rebuild change the supply chain seen by a downstream consumer?", "kind": "relationship", "answer_data": [ "intermediary agent chain", "point at which supplier changes", "downstream disclosure implication" ] } ], "data_elements": [ { "id": "de-supplier-agent", "name": "Supplying agent", "description": "Agent that supplied the component release to the consumer, distinct from the originating author.", "value_kind": "reference", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-001", "SRC-005" ] }, { "id": "de-originating-agent", "name": "Originating agent", "description": "Agent that authored or manufactured the component.", "value_kind": "reference", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-005" ] }, { "id": "de-role-assertion-basis", "name": "Role assertion basis", "description": "How each role claim was established: self-declared metadata, contractual record, or verified attestation.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-010" ] }, { "id": "de-steward-status", "name": "Steward status", "description": "Whether an open-source steward or equivalent non-commercial maintainer stands behind the component.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-010" ] } ], "artifacts": [ { "id": "a-supplier-role-record", "name": "Supplier and role record", "description": "Stored record of role assignments with the source document and basis for each claim.", "media_or_form": [ "role assignment record", "supplier declaration", "contractual reference" ], "serial": false, "identity_strategy": "Versioned canonical purl plus role term and agent identifier; agent identity resolved through the sibling organisation model, never re-keyed here.", "source_refs": [ "SRC-001", "SRC-010" ] } ], "inline_only_rationale": null }, { "id": "f-source-linkage", "name": "Source revision and repository linkage", "description": "The repository and exact revision corresponding to the release, and what if anything verifies that link beyond a self-declared URL.", "source_refs": [ "SRC-002", "SRC-006", "SRC-001", "SRC-017" ], "questions": [ { "id": "q-source-revision", "text": "Which source repository and exact revision correspond to this released artifact?", "kind": "provenance", "answer_data": [ "version control URL", "revision identifier such as a commit hash", "tag or release reference" ] }, { "id": "q-source-link-verification", "text": "What links the distributed artifact to that revision beyond a self-declared repository URL?", "kind": "validation", "answer_data": [ "attestation reference binding subject digest to revision", "reproducible rebuild result", "verification status" ] }, { "id": "q-source-unavailable", "text": "What is recorded when no source is available or the source link cannot be verified?", "kind": "exception", "answer_data": [ "unavailability reason", "source information note", "risk acceptance and approver" ] }, { "id": "q-source-carrier", "text": "Which qualifier or external reference carries the source location in each exchange representation?", "kind": "interoperability", "answer_data": [ "qualifier or field name per format", "value as exchanged", "mapping note" ] } ], "data_elements": [ { "id": "de-vcs-url", "name": "Version control URL", "description": "Location of the source repository associated with the component.", "value_kind": "text", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-002", "SRC-001" ] }, { "id": "de-source-revision", "name": "Source revision identifier", "description": "Exact revision, such as a commit digest, claimed to correspond to the release.", "value_kind": "identifier", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006" ] }, { "id": "de-source-link-verification", "name": "Source link verification status", "description": "Whether the artifact-to-revision link is unverified, attested or independently reproduced.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006", "SRC-017" ] } ], "artifacts": [ { "id": "a-source-distribution", "name": "Source distribution or repository snapshot", "description": "Retained source form of the release, or a snapshot reference sufficient to re-derive it.", "media_or_form": [ "source archive", "repository snapshot reference", "source information note" ], "serial": false, "identity_strategy": "Content digest of the source archive as primary identity; revision identifier plus repository URL as the governed reference.", "source_refs": [ "SRC-002", "SRC-006" ] } ], "inline_only_rationale": null } ] }, { "id": "l-build-and-signature", "name": "Build Provenance and Trust Verification", "description": "The attestation describing how the artifact was built and the signature material that makes it checkable.", "source_refs": [ "SRC-006", "SRC-007", "SRC-016", "SRC-017" ], "findings": [ { "id": "f-build-provenance", "name": "Build provenance attestation", "description": "The provenance predicate binding the artifact digest to a build platform, build type, parameters and time window, and the assurance level claimed from it.", "source_refs": [ "SRC-006", "SRC-007", "SRC-017" ], "questions": [ { "id": "q-build-definition", "text": "Which build platform, build type and external parameters produced this artifact?", "kind": "process", "answer_data": [ "build type URI", "builder identifier URI", "external parameter object", "internal parameters where disclosed" ] }, { "id": "q-build-window", "text": "When did the build start and finish, and how do those instants relate to publication?", "kind": "temporal", "answer_data": [ "build start instant", "build finish instant", "publication instant", "clock source and offset handling" ] }, { "id": "q-build-inputs", "text": "Which resolved dependencies and byproducts were recorded for the build, and how complete are they?", "kind": "evidence", "answer_data": [ "resolved dependency descriptors", "byproduct descriptors", "completeness caveat" ] }, { "id": "q-build-level-claim", "text": "Which provenance assurance level is claimed, and what concrete evidence supports the claim?", "kind": "measurement", "answer_data": [ "claimed level", "evidence per level requirement", "assessor identity and date" ] }, { "id": "q-build-subject-match", "text": "Is the attestation subject digest identical to the digest of the artifact actually distributed?", "kind": "validation", "answer_data": [ "subject digest", "distributed artifact digest", "match result and comparison time" ] } ], "data_elements": [ { "id": "de-build-type-uri", "name": "Build type URI", "description": "Type URI identifying the template for how the build was performed and how its parameters are interpreted.", "value_kind": "identifier", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006" ] }, { "id": "de-builder-id", "name": "Builder identifier", "description": "Type URI identifying the transitive closure of the trusted build platform.", "value_kind": "identifier", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006" ] }, { "id": "de-build-started-on", "name": "Build start instant", "description": "Event time at which the build run began, as reported by the build platform.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006" ] }, { "id": "de-build-finished-on", "name": "Build finish instant", "description": "Event time at which the build run completed.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006" ] }, { "id": "de-provenance-level-claim", "name": "Provenance level claim", "description": "Assurance level asserted for the build provenance, together with the assessing party.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006", "SRC-017" ] } ], "artifacts": [ { "id": "a-provenance-predicate", "name": "Build provenance predicate document", "description": "The provenance predicate as issued by the build platform, retained verbatim for re-verification.", "media_or_form": [ "provenance predicate document", "attestation payload" ], "serial": false, "identity_strategy": "Subject digest of the attested artifact plus predicate type URI; digest of the predicate document itself for the retained copy.", "source_refs": [ "SRC-006", "SRC-007" ] } ], "inline_only_rationale": null }, { "id": "f-signature-envelope", "name": "Signature, envelope and admission decision", "description": "Signature and attestation envelopes covering the artifact, the verification policy that gates admission, and how exceptions are authorised.", "source_refs": [ "SRC-007", "SRC-006", "SRC-016", "SRC-017" ], "questions": [ { "id": "q-signature-coverage", "text": "Which signatures or attestation envelopes cover this artifact, and which identity signed each?", "kind": "security", "answer_data": [ "envelope references", "signer identity per envelope", "predicate types covered" ] }, { "id": "q-signature-policy", "text": "Which verification policy must pass before the component is admitted, and what happens on failure?", "kind": "validation", "answer_data": [ "policy identifier and version", "required predicate and signer constraints", "failure behaviour such as block or quarantine" ] }, { "id": "q-signature-validity-window", "text": "When was each signature made, when does the trust material expire, and how is verification-at-time recorded?", "kind": "temporal", "answer_data": [ "signature instant", "trust material validity window", "verification instant and result" ] }, { "id": "q-signature-exception", "text": "On what basis may an unsigned or unverifiable component be accepted, and who authorises that?", "kind": "exception", "answer_data": [ "exception justification", "authorising agent", "exception expiry", "compensating control" ] } ], "data_elements": [ { "id": "de-signature-ref", "name": "Signature or envelope reference", "description": "Reference to a signed envelope covering an attestation or artifact for this release.", "value_kind": "reference", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-007" ] }, { "id": "de-signer-identity", "name": "Signer identity", "description": "Identity asserted by the signing material, resolved to an agent where possible.", "value_kind": "identifier", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-007", "SRC-006" ] }, { "id": "de-verification-policy-id", "name": "Verification policy identifier", "description": "Identifier and version of the admission policy applied to this component.", "value_kind": "identifier", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-017", "SRC-016" ] } ], "artifacts": [ { "id": "a-signed-envelope", "name": "Signed attestation envelope", "description": "The signed envelope carrying the statement, retained so verification can be re-run independently of the issuing platform.", "media_or_form": [ "signed envelope", "detached signature", "transparency log inclusion proof" ], "serial": true, "identity_strategy": "Digest of the envelope; subject digest plus predicate type as the governed reference; sequence number for successive envelopes over the same subject.", "source_refs": [ "SRC-007", "SRC-006" ] } ], "inline_only_rationale": null } ] } ] }, { "id": "b-legal-obligations", "name": "Licensing, Rights and Regulatory Obligations", "description": "The licence position of the component, the obligations that follow from redistributing it, and the regulatory duties that attach to shipping it.", "rationale": "Licence and copyright are minimum component-inventory fields, and SPDX distinguishes what a supplier declares from what a reviewer concludes. Regulatory duties such as the EU support period and vulnerability reporting deadlines attach to products containing the component and must be traceable to the component that triggers them.", "source_refs": [ "SRC-009", "SRC-001", "SRC-005", "SRC-010", "SRC-019" ], "layers": [ { "id": "l-licensing", "name": "Licence Determination and Obligations", "description": "Declared versus concluded licensing and the concrete obligations that follow.", "source_refs": [ "SRC-009", "SRC-001", "SRC-005" ], "findings": [ { "id": "f-license-determination", "name": "Declared and concluded licensing", "description": "The licence expression the supplier declares, the expression a reviewer concludes, and how ambiguity and choice under disjunction are recorded.", "source_refs": [ "SRC-009", "SRC-001", "SRC-005" ], "questions": [ { "id": "q-license-declared", "text": "What licence expression is declared by the supplier for this component release?", "kind": "definition", "answer_data": [ "declared licence expression", "location of the declaration", "acknowledgement status" ] }, { "id": "q-license-concluded", "text": "What licence has been concluded after review, and which agent made that determination?", "kind": "decision", "answer_data": [ "concluded licence expression", "determining agent", "determination rationale", "determination time" ] }, { "id": "q-license-operator-choice", "text": "Which operator semantics apply, and which option has been selected under a disjunctive expression?", "kind": "constraint", "answer_data": [ "parsed expression tree", "selected disjunct", "selection rationale and approver" ] }, { "id": "q-license-ambiguity", "text": "How are unlicensed, ambiguous or unasserted licence cases represented and escalated?", "kind": "exception", "answer_data": [ "ambiguity marker value", "escalation route", "blocking or non-blocking classification" ] } ], "data_elements": [ { "id": "de-declared-license", "name": "Declared licence expression", "description": "Licence expression as declared by the supplier, canonicalized to SPDX expression syntax where parseable.", "value_kind": "text", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-009", "SRC-001" ] }, { "id": "de-concluded-license", "name": "Concluded licence expression", "description": "Licence expression concluded by review, which may differ from the declaration.", "value_kind": "text", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-009", "SRC-001" ] }, { "id": "de-license-choice", "name": "Recorded licence choice", "description": "The disjunct selected by the adopting Dimension when the expression offers a choice.", "value_kind": "object", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-009" ] }, { "id": "de-license-determination-agent", "name": "Licence determining agent", "description": "Agent accountable for the concluded licence determination.", "value_kind": "reference", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-001", "SRC-009" ] } ], "artifacts": [ { "id": "a-license-determination-record", "name": "Licence determination record", "description": "Record of the declared and concluded expressions, evidence examined, choice made and approving agent.", "media_or_form": [ "licence determination record", "licence file extract", "review note" ], "serial": false, "identity_strategy": "Versioned canonical purl plus determination sequence; the determination is versioned rather than overwritten when re-reviewed.", "source_refs": [ "SRC-009", "SRC-001" ] } ], "inline_only_rationale": null }, { "id": "f-attribution-obligations", "name": "Attribution, notice and redistribution obligations", "description": "The concrete obligations triggered by redistributing the component and the evidence that they were met.", "source_refs": [ "SRC-001", "SRC-009", "SRC-005" ], "questions": [ { "id": "q-obligation-set", "text": "Which attribution, notice and source-offer obligations attach to redistributing this component?", "kind": "requirement", "answer_data": [ "obligation items with triggering clause", "obligation owner", "fulfilment channel" ] }, { "id": "q-obligation-notice-content", "text": "Which copyright statements and notice texts must be reproduced, and where were they taken from?", "kind": "composition", "answer_data": [ "copyright texts", "attribution texts", "extraction location and method" ] }, { "id": "q-obligation-linkage-variation", "text": "How do obligations differ between static linking, dynamic linking and unmodified redistribution?", "kind": "constraint", "answer_data": [ "obligation set per linkage kind", "applicable linkage for this usage", "legal review reference" ] }, { "id": "q-obligation-evidence", "text": "What record proves the obligations were satisfied for a specific distribution?", "kind": "evidence", "answer_data": [ "notices artifact reference", "distribution identifier", "fulfilment timestamp and actor" ] } ], "data_elements": [ { "id": "de-copyright-text", "name": "Copyright text", "description": "Copyright statement associated with the component or its contained files.", "value_kind": "text", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-005" ] }, { "id": "de-attribution-text", "name": "Attribution text", "description": "Text that must be reproduced when redistributing the component.", "value_kind": "text", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001" ] }, { "id": "de-obligation-item", "name": "Obligation item", "description": "A single derived obligation with its trigger, owner and fulfilment state.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-009", "SRC-001" ] } ], "artifacts": [ { "id": "a-third-party-notices", "name": "Third-party notices document", "description": "Assembled notice and attribution document shipped with or alongside a distribution containing the component.", "media_or_form": [ "notices document", "attribution bundle", "source offer record" ], "serial": true, "identity_strategy": "Distribution identifier plus notices revision sequence; content digest for each issued revision.", "source_refs": [ "SRC-001", "SRC-009" ] } ], "inline_only_rationale": null } ] }, { "id": "l-regulatory-duties", "name": "Regulatory and Disclosure Duties", "description": "Support-period, due-diligence, disclosure and incident-reporting duties triggered by shipping the component in a regulated market.", "source_refs": [ "SRC-010", "SRC-019", "SRC-017", "SRC-005" ], "findings": [ { "id": "f-support-and-diligence", "name": "Support period and third-party due diligence", "description": "The support period determined for products containing the component and the due-diligence step required before integrating a third-party or open-source component.", "source_refs": [ "SRC-010", "SRC-019", "SRC-017" ], "questions": [ { "id": "q-support-period-determined", "text": "What support period has the responsible manufacturer determined for products containing this component?", "kind": "requirement", "answer_data": [ "support period end date", "determining manufacturer", "basis for the determination" ] }, { "id": "q-regulatory-authority", "text": "Which regulator, market and legal instrument imposes obligations on this component's use?", "kind": "authority", "answer_data": [ "applicable regulation identifier", "market or jurisdiction", "competent authority" ] }, { "id": "q-support-communication", "text": "How and when is the end of the support period communicated to the purchaser?", "kind": "temporal", "answer_data": [ "communication channel", "communication instant", "wording of the end-date statement" ] }, { "id": "q-due-diligence-step", "text": "Which due-diligence step was performed before integrating this third-party or open-source component?", "kind": "process", "answer_data": [ "due-diligence checklist reference", "performing agent", "completion time", "outcome and residual risk" ] } ], "data_elements": [ { "id": "de-support-period-end", "name": "Support period end date", "description": "Date until which vulnerabilities in products containing this component will be handled by the responsible manufacturer.", "value_kind": "date", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-010" ] }, { "id": "de-applicable-regulation", "name": "Applicable regulation", "description": "Regulatory instrument asserted to apply to the component in a given market.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-010", "SRC-019" ] }, { "id": "de-due-diligence-record-ref", "name": "Due-diligence record reference", "description": "Reference to the completed due-diligence assessment for this component.", "value_kind": "reference", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-010", "SRC-017" ] } ], "artifacts": [ { "id": "a-diligence-declaration", "name": "Due-diligence and support-period declaration", "description": "Retained declaration recording the diligence performed and the support period committed for the component in a given market.", "media_or_form": [ "due-diligence assessment", "support period declaration", "technical documentation extract" ], "serial": true, "identity_strategy": "Versioned canonical purl plus market identifier and declaration sequence; superseded declarations retained, never overwritten.", "source_refs": [ "SRC-010", "SRC-019" ] } ], "inline_only_rationale": null }, { "id": "f-disclosure-and-reporting", "name": "Component disclosure and incident reporting duties", "description": "What component data must be disclosed to customers or authorities, to whom, in what form, and on what deadlines once a vulnerability is actively exploited.", "source_refs": [ "SRC-010", "SRC-019", "SRC-005", "SRC-018" ], "questions": [ { "id": "q-disclosure-fields", "text": "Which component data fields must be disclosed, to whom, and in which machine-readable form?", "kind": "requirement", "answer_data": [ "required field list", "recipient class", "exchange format and version" ] }, { "id": "q-reporting-deadlines", "text": "Which reporting deadlines apply once a vulnerability in this component is actively exploited?", "kind": "temporal", "answer_data": [ "early warning deadline", "notification deadline", "final report deadline", "clock start event" ] }, { "id": "q-disclosure-entitlement", "text": "Who is entitled to receive the component disclosure, and under what confidentiality terms?", "kind": "access", "answer_data": [ "entitled recipient list", "legal basis", "confidentiality terms", "expiry of the entitlement" ] }, { "id": "q-disclosure-redaction", "text": "What is disclosed when component contents are commercially sensitive or genuinely unknown?", "kind": "exception", "answer_data": [ "redaction basis", "known-unknown statement", "approving agent" ] } ], "data_elements": [ { "id": "de-disclosure-obligation", "name": "Disclosure obligation", "description": "A required disclosure with its recipient, form and legal basis.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-010", "SRC-019" ] }, { "id": "de-reporting-deadline", "name": "Reporting deadline", "description": "Elapsed-time deadline measured from the triggering event for a required notification.", "value_kind": "duration", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-010" ] }, { "id": "de-redaction-basis", "name": "Redaction basis", "description": "Recorded justification for withholding component detail from a disclosure.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-010" ] } ], "artifacts": [ { "id": "a-disclosure-package", "name": "Component disclosure package", "description": "The assembled, machine-readable disclosure issued to a named recipient, retained with its redaction record.", "media_or_form": [ "component inventory export", "regulator notification", "customer disclosure record" ], "serial": true, "identity_strategy": "Recipient identifier plus disclosure sequence and issue instant; content digest of the issued package.", "source_refs": [ "SRC-010", "SRC-005", "SRC-018" ] } ], "inline_only_rationale": null } ] } ] }, { "id": "b-lifecycle-and-exposure", "name": "Lifecycle State, Exposure and Health", "description": "The published state of a release over time, its vulnerability exposure, and the signals used to decide whether to adopt or retire it.", "rationale": "Registries implement materially different lifecycle regimes: yanking makes a release invisible to resolvers without deleting it, deprecation warns without blocking, and unpublish windows differ per registry. Vulnerability affectedness is a computed verdict over advisory ranges, not a stored attribute, and must carry its assessment time and evidence.", "source_refs": [ "SRC-014", "SRC-015", "SRC-008", "SRC-001", "SRC-016", "SRC-005", "SRC-010" ], "layers": [ { "id": "l-release-lifecycle", "name": "Release State and Support Window", "description": "Published state transitions of a release and the maintenance window and replacement path around it.", "source_refs": [ "SRC-014", "SRC-015", "SRC-001", "SRC-010" ], "findings": [ { "id": "f-release-state", "name": "Release state and transitions", "description": "The current published state of the release, the transitions permitted, and how a resolver must behave in each state.", "source_refs": [ "SRC-014", "SRC-015", "SRC-001" ], "questions": [ { "id": "q-state-current", "text": "What is the current published state of this release in its registry of record?", "kind": "state", "answer_data": [ "state term such as pre-release, published, deprecated, yanked, withdrawn or removed", "state as reported by the registry", "observation time of the state read" ] }, { "id": "q-state-transitions", "text": "Which state transitions are permitted, who may perform them, and which are irreversible?", "kind": "lifecycle", "answer_data": [ "permitted transition list", "authorised actor per transition", "reversibility flag" ] }, { "id": "q-state-trigger-event", "text": "Which event caused the most recent state change, and what reason string was recorded?", "kind": "event", "answer_data": [ "triggering event reference", "reason string", "event time", "actor" ] }, { "id": "q-state-resolver-behaviour", "text": "How must a resolver behave when a required version is yanked or deprecated?", "kind": "constraint", "answer_data": [ "selection rule for the state", "pinned or lock-file override behaviour", "warning obligation" ] } ], "data_elements": [ { "id": "de-release-state", "name": "Release state", "description": "Current lifecycle state of the release as reported by the registry of record.", "value_kind": "code", "cardinality": "1", "required": true, "source_refs": [ "SRC-014", "SRC-015" ] }, { "id": "de-state-changed-at", "name": "State change event time", "description": "Event time of the most recent state transition, distinct from when the Dimension observed it.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-014", "SRC-008" ] }, { "id": "de-state-change-reason", "name": "State change reason", "description": "Free-text reason recorded with the transition, such as a yank reason, surfaced to consumers where available.", "value_kind": "text", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-014", "SRC-015" ] } ], "artifacts": [ { "id": "a-state-change-log", "name": "Release state change log", "description": "Append-only log of observed state transitions for the release with reasons and observation times.", "media_or_form": [ "state transition log", "registry state snapshot" ], "serial": true, "identity_strategy": "Versioned canonical purl plus monotonic entry sequence; entry sequence orders observations and is never parsed as a date.", "source_refs": [ "SRC-014", "SRC-015" ] } ], "inline_only_rationale": null }, { "id": "f-support-window", "name": "Maintenance window, end of life and replacement", "description": "Built, released and valid-until instants, maintenance signals, accountable maintainer and the recommended successor release.", "source_refs": [ "SRC-001", "SRC-010", "SRC-016" ], "questions": [ { "id": "q-window-instants", "text": "What are the built, released and valid-until instants recorded for this release?", "kind": "temporal", "answer_data": [ "built time", "release time", "valid until time", "source of each instant" ] }, { "id": "q-window-successor", "text": "Which release is the recommended replacement, and what migration cost has been recorded?", "kind": "decision", "answer_data": [ "successor coordinate", "breaking-change summary", "estimated migration effort", "recommendation owner" ] }, { "id": "q-window-maintenance-signal", "text": "Which signals indicate this component is no longer actively maintained?", "kind": "measurement", "answer_data": [ "maintenance signal values", "measurement instant", "threshold applied" ] }, { "id": "q-window-accountability", "text": "Who is accountable for maintenance now, and has stewardship been transferred?", "kind": "ownership", "answer_data": [ "current maintaining agent", "transfer event and date", "support level term" ] } ], "data_elements": [ { "id": "de-built-time", "name": "Built time", "description": "Event time at which the release artifact was built.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-001", "SRC-006" ] }, { "id": "de-release-time", "name": "Release time", "description": "Event time at which the release was published by the registry of record.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-001" ] }, { "id": "de-valid-until-time", "name": "Valid until time", "description": "Time after which the release should no longer be relied upon, where the supplier declares one.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-001", "SRC-010" ] }, { "id": "de-successor-ref", "name": "Successor release reference", "description": "Reference to the recommended replacement release.", "value_kind": "reference", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-014", "SRC-015" ] }, { "id": "de-support-level", "name": "Support level", "description": "Declared level of support offered for the release.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001" ] } ], "artifacts": [ { "id": "a-lifecycle-notice", "name": "Lifecycle and end-of-life notice", "description": "Retained supplier or steward notice announcing deprecation, end of maintenance or a replacement path.", "media_or_form": [ "end-of-life notice", "deprecation message", "support policy extract" ], "serial": true, "identity_strategy": "Versionless canonical purl plus notice sequence and issue instant; content digest of the retained notice.", "source_refs": [ "SRC-001", "SRC-010", "SRC-015" ] } ], "inline_only_rationale": null } ] }, { "id": "l-vulnerability-exposure", "name": "Vulnerability Exposure and Remediation", "description": "Whether a specific version is affected by published advisories and what was decided about it.", "source_refs": [ "SRC-008", "SRC-005", "SRC-010", "SRC-017" ], "findings": [ { "id": "f-affectedness", "name": "Vulnerability affectedness of a version", "description": "The computed verdict on whether this exact version falls inside an advisory's affected ranges, and the evidence behind it.", "source_refs": [ "SRC-008", "SRC-011", "SRC-005" ], "questions": [ { "id": "q-affected-advisories", "text": "Which advisories declare this exact version affected, through which range type and events?", "kind": "relationship", "answer_data": [ "advisory identifiers and aliases", "range type", "introduced, fixed, last-affected and limit events", "matched package coordinate" ] }, { "id": "q-affected-computation", "text": "How is affectedness computed for a version not explicitly enumerated in the advisory?", "kind": "validation", "answer_data": [ "range evaluation rule applied", "ecosystem ordering used", "verdict and residual uncertainty" ] }, { "id": "q-affected-advisory-time", "text": "When was each advisory published, last modified or withdrawn, and when was this assessment made?", "kind": "temporal", "answer_data": [ "advisory published instant", "advisory modified instant", "withdrawn instant if any", "assessment instant" ] }, { "id": "q-affected-severity", "text": "What severity is asserted for each advisory, by which scoring system and which source?", "kind": "measurement", "answer_data": [ "severity type", "score value", "scoring source", "local severity override with rationale" ] } ], "data_elements": [ { "id": "de-advisory-id", "name": "Advisory identifier", "description": "Identifier of an advisory asserted to affect this component, with any aliases.", "value_kind": "identifier", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-008" ] }, { "id": "de-affected-range", "name": "Affected range", "description": "Advisory range and event set evaluated against this version.", "value_kind": "object", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-008" ] }, { "id": "de-affectedness-verdict", "name": "Affectedness verdict", "description": "Computed verdict for this version against a specific advisory, with residual uncertainty.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-008" ] }, { "id": "de-assessed-at", "name": "Assessment instant", "description": "Observation time at which the affectedness verdict was computed.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-008" ] } ], "artifacts": [ { "id": "a-affectedness-assessment", "name": "Affectedness assessment record", "description": "Stored verdict per advisory with the advisory snapshot, ranges evaluated, ordering used and assessment instant.", "media_or_form": [ "affectedness assessment record", "advisory snapshot", "scan result" ], "serial": true, "identity_strategy": "Versioned canonical purl plus advisory identifier plus assessment sequence; advisory identity owned by the sibling advisory model.", "source_refs": [ "SRC-008" ] } ], "inline_only_rationale": null }, { "id": "f-remediation-status", "name": "Exploitability, remediation and exception", "description": "Whether an advisory is exploitable in the component's actual usage, what remediation was chosen, and under what time-bounded exception an affected version may remain.", "source_refs": [ "SRC-008", "SRC-005", "SRC-010", "SRC-017" ], "questions": [ { "id": "q-remediation-exploitability", "text": "What is the exploitability status of this advisory in the component's actual usage context?", "kind": "state", "answer_data": [ "exploitability status term", "justification", "analysing agent", "analysis instant" ] }, { "id": "q-remediation-decision", "text": "Which remediation was chosen, and who approved it?", "kind": "decision", "answer_data": [ "remediation option chosen", "approving agent", "approval instant", "residual risk statement" ] }, { "id": "q-remediation-path", "text": "What is the fixed version and the concrete upgrade path from the currently adopted version?", "kind": "process", "answer_data": [ "fixed version", "intermediate versions required", "breaking changes on the path" ] }, { "id": "q-remediation-exception", "text": "Under what documented exception may an affected version remain in use, and until when?", "kind": "exception", "answer_data": [ "exception identifier", "compensating controls", "expiry date", "review owner" ] } ], "data_elements": [ { "id": "de-exploitability-status", "name": "Exploitability status", "description": "Assessed exploitability of an advisory in this component's usage context.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-008", "SRC-005" ] }, { "id": "de-fixed-version", "name": "Fixed version", "description": "Version in which the advisory is stated to be fixed, preferred over a last-affected boundary.", "value_kind": "text", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-008" ] }, { "id": "de-remediation-decision", "name": "Remediation decision", "description": "Chosen remediation option with its approver.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-017", "SRC-010" ] }, { "id": "de-exception-expiry", "name": "Exception expiry date", "description": "Date on which a granted exception lapses and the exposure must be re-decided.", "value_kind": "date", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-010", "SRC-017" ] } ], "artifacts": [ { "id": "a-remediation-record", "name": "Remediation and exception record", "description": "Decision record covering exploitability analysis, chosen remediation, approvals and any time-bounded exception.", "media_or_form": [ "exploitability statement", "remediation decision record", "exception grant" ], "serial": true, "identity_strategy": "Versioned canonical purl plus advisory identifier plus decision sequence; decisions are appended, never edited in place.", "source_refs": [ "SRC-008", "SRC-017", "SRC-010" ] } ], "inline_only_rationale": null } ] }, { "id": "l-health-and-evidence", "name": "Health Signals and Identification Evidence", "description": "Measured project health used for adoption decisions and the evidence supporting the claim that this component is present at all.", "source_refs": [ "SRC-016", "SRC-005", "SRC-017" ], "findings": [ { "id": "f-project-health", "name": "Maintenance and security-practice health signals", "description": "Measured checks over the component's project used as adoption signals, with the tool, revision and measurement time that make them comparable.", "source_refs": [ "SRC-016", "SRC-017" ], "questions": [ { "id": "q-health-checks", "text": "Which health and security-practice checks were run against this component's project, and what results were produced?", "kind": "measurement", "answer_data": [ "check names and risk levels", "per-check score on a fixed scale", "aggregate score" ] }, { "id": "q-health-threshold", "text": "Which signals materially change the adoption decision, and what threshold applies?", "kind": "quality", "answer_data": [ "gating check list", "threshold value per gating check", "decision outcome" ] }, { "id": "q-health-staleness", "text": "When were the signals measured, and how quickly do they become stale?", "kind": "temporal", "answer_data": [ "measurement instant", "validity period", "re-measurement trigger" ] }, { "id": "q-health-tooling", "text": "Which tool and tool version produced each signal, and against which repository revision?", "kind": "provenance", "answer_data": [ "tool identifier and version", "evaluated repository and revision", "configuration used" ] } ], "data_elements": [ { "id": "de-health-check-result", "name": "Health check result", "description": "Result of a single named health or security-practice check with its risk level.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-016" ] }, { "id": "de-health-score", "name": "Health score", "description": "Numeric score for a check or aggregate on the tool's fixed scale.", "value_kind": "number", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-016" ] }, { "id": "de-measured-at", "name": "Measurement instant", "description": "Observation time at which the health signals were measured.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-016" ] }, { "id": "de-measuring-tool", "name": "Measuring tool", "description": "Identifier and version of the tool that produced the health signals.", "value_kind": "identifier", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-016", "SRC-005" ] } ], "artifacts": [ { "id": "a-health-report", "name": "Project health assessment report", "description": "Retained report of check results and scores with tool, revision and measurement instant.", "media_or_form": [ "health assessment report", "check result set" ], "serial": true, "identity_strategy": "Versionless canonical purl plus evaluated revision plus measurement sequence; report digest for the retained copy.", "source_refs": [ "SRC-016" ] } ], "inline_only_rationale": null }, { "id": "f-identification-evidence", "name": "Evidence and confidence of component identification", "description": "What evidence supports the claim that this component is present in a given artifact, with what confidence, produced by which technique and context.", "source_refs": [ "SRC-005", "SRC-001", "SRC-018", "SRC-016" ], "questions": [ { "id": "q-evidence-basis", "text": "What evidence supports the claim that this component is present in the analysed artifact?", "kind": "evidence", "answer_data": [ "evidence items such as manifest entry, file digest match, filename heuristic or binary analysis", "location of each evidence item", "evidence strength" ] }, { "id": "q-evidence-confidence", "text": "What confidence is attached to the identification, and how was that confidence computed?", "kind": "quality", "answer_data": [ "confidence value", "computation method", "contributing evidence weights" ] }, { "id": "q-evidence-conflict", "text": "How are two conflicting identifications of the same artifact reconciled?", "kind": "validation", "answer_data": [ "conflict resolution rule", "surviving identification", "retained losing identification and reason" ] }, { "id": "q-evidence-generation-context", "text": "Which tool, technique and generation context produced the identification?", "kind": "provenance", "answer_data": [ "tool identifier and version", "technique term", "generation context such as source, build or post-build analysis" ] } ], "data_elements": [ { "id": "de-identification-technique", "name": "Identification technique", "description": "Method by which the component was identified in an artifact.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005" ] }, { "id": "de-identification-confidence", "name": "Identification confidence", "description": "Confidence value attached to an identification claim.", "value_kind": "number", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-005" ] }, { "id": "de-generation-context", "name": "Generation context", "description": "Point in the lifecycle at which the identification was generated, such as source analysis, build time or post-build analysis.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-005", "SRC-018" ] } ], "artifacts": [ { "id": "a-identification-evidence-record", "name": "Identification evidence record", "description": "Structured evidence set substantiating a component identification, retained so contested identifications can be re-examined.", "media_or_form": [ "evidence structure", "occurrence list", "match report" ], "serial": true, "identity_strategy": "Analysed artifact digest plus claimed canonical purl plus evidence-set sequence.", "source_refs": [ "SRC-005" ] } ], "inline_only_rationale": null } ] } ] }, { "id": "b-distribution-and-governance", "name": "Distribution, Availability and Record Governance", "description": "Where the component is obtained, how long it stays obtainable, and how assertions about it are governed and exchanged.", "rationale": "The registry of record determines both retrievability and deletion behaviour, and those behaviours differ sharply between ecosystems; namespace control is also the principal defence against substitution attacks. Separately, every fact in this model is an assertion by some party at some time, and interoperability with exchange formats is lossy in ways that must be stated rather than assumed.", "source_refs": [ "SRC-015", "SRC-014", "SRC-002", "SRC-013", "SRC-005", "SRC-001", "SRC-008", "SRC-018" ], "layers": [ { "id": "l-distribution-channel", "name": "Distribution Channel and Availability", "description": "Registry of record, retrieval endpoints, and the deletion and retention behaviour that governs continued availability.", "source_refs": [ "SRC-002", "SRC-015", "SRC-013", "SRC-014" ], "findings": [ { "id": "f-registry-location", "name": "Registry of record and retrieval location", "description": "Where the component is retrievable, which registry's metadata prevails, and what prevents namespace substitution between internal and public sources.", "source_refs": [ "SRC-002", "SRC-015", "SRC-013" ], "questions": [ { "id": "q-registry-endpoints", "text": "From which registry, repository URL and mirrors is this component retrievable, and which is the registry of record?", "kind": "spatial", "answer_data": [ "repository URL qualifier", "download URL", "mirror endpoints", "registry-of-record designation" ] }, { "id": "q-registry-precedence", "text": "Which registry's metadata prevails when a public and an internal registry disagree about the same coordinate?", "kind": "authority", "answer_data": [ "precedence rule", "conflict instances observed", "resolution owner" ] }, { "id": "q-registry-substitution-control", "text": "What controls prevent substitution between an internal namespace and a public one with the same name?", "kind": "security", "answer_data": [ "namespace reservation record", "resolver configuration constraint", "alerting rule for new public matches" ] }, { "id": "q-registry-access-requirements", "text": "Which credentials or entitlements are required to retrieve this component?", "kind": "access", "answer_data": [ "authentication method", "entitlement or licence key requirement", "secret manager reference, never the secret itself" ] } ], "data_elements": [ { "id": "de-repository-url", "name": "Repository URL", "description": "Registry or repository endpoint qualifying the coordinate when it is not the ecosystem default.", "value_kind": "text", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-002" ] }, { "id": "de-download-location", "name": "Download location", "description": "Direct retrieval location for the release artifact.", "value_kind": "text", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-002", "SRC-013" ] }, { "id": "de-registry-of-record", "name": "Registry of record", "description": "Designation of which endpoint is authoritative for this component's metadata and state.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-015", "SRC-002" ] } ], "artifacts": [ { "id": "a-retrieval-configuration", "name": "Registry endpoint and retrieval configuration", "description": "Configuration that binds a coordinate to its authoritative endpoints and namespace reservations, excluding all secret material.", "media_or_form": [ "resolver configuration", "registry endpoint record", "namespace reservation entry" ], "serial": false, "identity_strategy": "purl type plus namespace plus registry endpoint; secrets referenced only by secret manager entry identifier.", "source_refs": [ "SRC-002", "SRC-015" ] } ], "inline_only_rationale": null }, { "id": "f-availability-retention", "name": "Availability, removal and retention", "description": "How long the artifact remains retrievable upstream, under what conditions the publisher may remove it, and what internal copy guarantees continuity.", "source_refs": [ "SRC-015", "SRC-014", "SRC-004", "SRC-017" ], "questions": [ { "id": "q-retention-upstream", "text": "How long will this artifact remain retrievable from the registry of record, and under which published policy?", "kind": "retention", "answer_data": [ "retention policy reference", "guaranteed availability window", "policy observation time" ] }, { "id": "q-retention-removal-conditions", "text": "Under which conditions may the publisher remove this release, and may the name and version then be reused?", "kind": "constraint", "answer_data": [ "removal window and eligibility conditions", "name and version reuse rule", "cooldown period" ] }, { "id": "q-retention-internal-copy", "text": "Which internal copy or archive guarantees continued availability once upstream removal occurs?", "kind": "process", "answer_data": [ "archive location", "copy digest and copy time", "restoration procedure" ] }, { "id": "q-retention-pinned-builds", "text": "What happens to builds already pinned to a version that has been removed upstream?", "kind": "exception", "answer_data": [ "impact assessment", "fallback source", "remediation deadline" ] } ], "data_elements": [ { "id": "de-unpublish-window", "name": "Unpublish window", "description": "Period after publication during which the publisher may remove the release without further conditions.", "value_kind": "duration", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-015" ] }, { "id": "de-name-reuse-permitted", "name": "Name and version reuse permitted", "description": "Whether the registry permits reuse of a coordinate after removal.", "value_kind": "boolean", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-015", "SRC-004" ] }, { "id": "de-archive-copy-location", "name": "Archive copy location", "description": "Internal location holding a verified copy of the artifact for continuity.", "value_kind": "text", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-017" ] } ], "artifacts": [ { "id": "a-archive-entry", "name": "Internal artifact archive entry", "description": "Verified internal copy of the release artifact with its digest, copy time and provenance of the copy operation.", "media_or_form": [ "archived artifact copy", "archive index entry" ], "serial": true, "identity_strategy": "Original artifact digest as identity; archive entry sequence and copy instant recorded separately and never used as identity.", "source_refs": [ "SRC-017", "SRC-013", "SRC-015" ] } ], "inline_only_rationale": null } ] }, { "id": "l-record-governance", "name": "Assertion Provenance and Format Projection", "description": "How facts about the component are attributed and timed, and how the record projects into exchange formats without silent loss.", "source_refs": [ "SRC-008", "SRC-005", "SRC-001", "SRC-018", "SRC-006" ], "findings": [ { "id": "f-assertion-provenance", "name": "Assertion provenance and record currency", "description": "Who asserted each fact about the component, from which source, at which event time and which observation time, and how conflicts are resolved.", "source_refs": [ "SRC-008", "SRC-001", "SRC-006", "SRC-005" ], "questions": [ { "id": "q-assertion-attribution", "text": "Who asserted each recorded fact about this component, and from which source document?", "kind": "provenance", "answer_data": [ "asserting agent", "source document reference and digest", "assertion method" ] }, { "id": "q-assertion-time-separation", "text": "How are event time, observation time and ingestion time recorded and distinguished for the same fact?", "kind": "temporal", "answer_data": [ "event time value", "observation time value", "ingestion time value", "rule applied when the source supplies only one of them" ] }, { "id": "q-assertion-staleness", "text": "How stale is each recorded fact, and what refresh obligation applies?", "kind": "quality", "answer_data": [ "age since observation", "maximum acceptable age", "refresh trigger and owner" ] }, { "id": "q-assertion-conflict", "text": "How is a conflicting assertion from two sources resolved and recorded?", "kind": "validation", "answer_data": [ "source precedence rule", "surviving value", "retained conflicting value and rationale" ] } ], "data_elements": [ { "id": "de-asserting-agent", "name": "Asserting agent", "description": "Agent or system that made a recorded claim about the component.", "value_kind": "reference", "cardinality": "1..n", "required": true, "source_refs": [ "SRC-001", "SRC-008" ] }, { "id": "de-event-time", "name": "Event time", "description": "Time at which the asserted real-world event occurred, distinct from when it was observed.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-006", "SRC-008" ] }, { "id": "de-observed-at", "name": "Observation time", "description": "Time at which the Dimension observed or retrieved the fact from its source.", "value_kind": "timestamp", "cardinality": "1", "required": true, "source_refs": [ "SRC-008", "SRC-016" ] }, { "id": "de-ingested-at", "name": "Ingestion time", "description": "Time at which the observed fact was written into the Dimension's store.", "value_kind": "timestamp", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-008" ] } ], "artifacts": [ { "id": "a-assertion-ledger-entry", "name": "Assertion ledger entry", "description": "Append-only entry recording one claim, its asserting agent, source, evidence and the three distinct times.", "media_or_form": [ "assertion ledger entry", "source snapshot reference" ], "serial": true, "identity_strategy": "Subject identifier plus predicate plus asserting agent plus monotonic entry sequence; entry sequence is ordering only and is never treated as a date.", "source_refs": [ "SRC-008", "SRC-001" ] } ], "inline_only_rationale": null }, { "id": "f-format-projection", "name": "Format projection and interoperability", "description": "Which exchange formats the component record must project into, which fields are lossy in each direction, and which representation is authoritative on disagreement.", "source_refs": [ "SRC-001", "SRC-005", "SRC-018", "SRC-002", "SRC-009" ], "questions": [ { "id": "q-projection-targets", "text": "Which exchange formats must this component record project into, and at which versions?", "kind": "interoperability", "answer_data": [ "target format identifiers and versions", "profile or subset used", "projection direction supported" ] }, { "id": "q-projection-mandatory-gaps", "text": "Which fields are mandatory in a target format but optional here, and how are the gaps filled?", "kind": "constraint", "answer_data": [ "mandatory field list per format", "fill strategy or explicit no-assertion value", "approval for any synthesised value" ] }, { "id": "q-projection-roundtrip", "text": "How is a round-trip projection validated, and what is the acceptance criterion?", "kind": "validation", "answer_data": [ "round-trip test procedure", "fields expected to be lossy", "pass or fail criterion and result" ] }, { "id": "q-projection-authoritative", "text": "Which representation is authoritative when two exported forms of this component disagree?", "kind": "classification", "answer_data": [ "authoritative representation designation", "reconciliation procedure", "owner of the reconciliation" ] } ], "data_elements": [ { "id": "de-target-format", "name": "Target exchange format", "description": "Format and version into which the component record is projected.", "value_kind": "code", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-005", "SRC-018" ] }, { "id": "de-field-mapping", "name": "Field mapping", "description": "Mapping between a model data element and its counterpart in a target format, with directionality.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-005" ] }, { "id": "de-lossiness-note", "name": "Lossiness note", "description": "Recorded statement of what is lost or approximated in a given projection direction.", "value_kind": "text", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005", "SRC-002" ] }, { "id": "de-roundtrip-result", "name": "Round-trip result", "description": "Outcome of validating a projection round trip against the acceptance criterion.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-001", "SRC-005" ] } ], "artifacts": [ { "id": "a-mapping-report", "name": "Format mapping and round-trip test report", "description": "Documented field mapping per target format with the executed round-trip test results and known lossy fields.", "media_or_form": [ "mapping table", "round-trip test report", "conformance note" ], "serial": true, "identity_strategy": "Model version plus target format identifier and version plus report sequence; report digest for the retained copy.", "source_refs": [ "SRC-001", "SRC-005", "SRC-018" ] } ], "inline_only_rationale": null }, { "id": "f-sbom-reference-edge", "name": "Containment and SBOM reference", "description": "A package typically contains files and may contain sub-packages. SPDX contains, expandsTo, hasDistributionArtifact and packagedBy describe those edges. CycloneDX metadata.component and compositions describe the root and relationship completeness. The SBOM document is WM-SFT-012; this package references it rather than embedding document identity as its own identity.", "source_refs": [ "SRC-001", "SRC-021", "SRC-005", "SRC-030" ], "questions": [ { "id": "f-sbom-reference-edge-q01", "text": "Which files, sub-packages or expanded artifacts does this package contain or distribute?", "kind": "composition", "answer_data": [ "Contained element references", "Relationship types contains, expandsTo, hasDistributionArtifact, packagedBy", "Whether containment is complete" ] }, { "id": "f-sbom-reference-edge-q02", "text": "Which SBOM documents (WM-SFT-012) describe this package as a component or root?", "kind": "relationship", "answer_data": [ "SBOM document identifiers or serial numbers as foreign keys", "Role of this package in each SBOM (root, component, tool)" ] }, { "id": "f-sbom-reference-edge-q03", "text": "What relationship completeness is asserted for this package's composition: complete, incomplete, unknown or a CycloneDX composition aggregate?", "kind": "quality", "answer_data": [ "Completeness code", "Unknown-unknown versus known-unknown notes" ] }, { "id": "f-sbom-reference-edge-q04", "text": "Is this package the SPDX rootElement or CycloneDX metadata.component of an inventory, or only a nested component?", "kind": "interoperability", "answer_data": [ "Root versus nested role", "Hosting document spec (SPDX 3.x, CycloneDX 1.6 or other)" ] }, { "id": "f-sbom-reference-edge-q05", "text": "What pedigree of ancestors, descendants, variants or commits is recorded for this component?", "kind": "provenance", "answer_data": [ "Ancestor package references", "Descendant and variant references", "Commit identifiers if present" ] } ], "data_elements": [ { "id": "f-sbom-reference-edge-data01", "name": "Contained element references", "description": "References to files or sub-packages contained in this package.", "value_kind": "collection", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-001", "SRC-021" ] }, { "id": "f-sbom-reference-edge-data02", "name": "SBOM document reference", "description": "Foreign key to a WM-SFT-012 SBOM that inventories this package.", "value_kind": "reference", "cardinality": "0..n", "required": false, "source_refs": [ "SRC-005", "SRC-030" ] }, { "id": "f-sbom-reference-edge-data03", "name": "Relationship completeness", "description": "Asserted completeness of containment and dependency edges.", "value_kind": "code", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-005", "SRC-031" ] }, { "id": "f-sbom-reference-edge-data04", "name": "Pedigree", "description": "Ancestors, descendants, variants and commits.", "value_kind": "object", "cardinality": "0..1", "required": false, "source_refs": [ "SRC-005" ] } ], "artifacts": [], "inline_only_rationale": "Containment and SBOM links are typed references. The SBOM document is a sibling artifact governed by WM-SFT-012; files inside the archive are not duplicated here as first-class entities. The package archive itself is recorded under distribution-and-integrity." } ] } ] } ] }, "functions": [ { "id": "fn-normalize-coordinate", "name": "Normalize and compare package coordinate", "description": "Produce the canonical purl for a component or release and decide whether two coordinates denote the same thing.", "inputs": [ "raw coordinate or purl string", "purl type", "registry endpoint context" ], "outputs": [ "canonical purl", "normalization decisions applied", "equality or inequality verdict against a candidate" ], "preconditions": [ "purl type is known and lowercase-normalizable", "type-specific case and encoding rules are available for the type" ], "effects": [ "Canonical identity is stored and used as the comparison key for all downstream operations", "Unrecognized or ambiguous types are raised as gaps rather than silently defaulted" ], "source_refs": [ "SRC-002", "SRC-003" ] }, { "id": "fn-verify-artifact-integrity", "name": "Verify artifact integrity", "description": "Verify retrieved bytes against the recorded digest before the artifact is consumed or archived.", "inputs": [ "retrieved byte stream", "recorded digest in algorithm:encoded form", "accepted algorithm policy" ], "outputs": [ "verification outcome", "computed digest", "verification instant and actor" ], "preconditions": [ "At least one digest is recorded for the artifact", "The digest algorithm is on the accepted list" ], "effects": [ "A mismatch quarantines the artifact and never overwrites the recorded digest", "Verification outcome and time are appended to the assertion ledger" ], "source_refs": [ "SRC-013", "SRC-007", "SRC-017" ] }, { "id": "fn-resolve-dependency-closure", "name": "Resolve dependency closure", "description": "Expand declared constraints into a concrete transitive set of component releases at a stated instant.", "inputs": [ "root component coordinate", "declared dependency manifest", "registry state and resolver configuration" ], "outputs": [ "resolved component set with pinned versions and digests", "direct versus transitive classification", "completeness statement including known unknowns" ], "preconditions": [ "Version scheme is declared or inferable for each constraint", "Registry endpoints are reachable or a cached snapshot is available" ], "effects": [ "Resolution instant is recorded so the closure can be reproduced or invalidated", "Unresolvable constraints are recorded as explicit known unknowns rather than dropped" ], "source_refs": [ "SRC-006", "SRC-005", "SRC-002" ] }, { "id": "fn-verify-build-provenance", "name": "Verify build provenance", "description": "Check that a provenance attestation exists for the artifact digest, is signed by an accepted identity and satisfies the admission policy.", "inputs": [ "artifact digest", "provenance predicate and signed envelope", "verification policy" ], "outputs": [ "verification result", "builder identity and build type as verified", "claimed assurance level with supporting evidence" ], "preconditions": [ "Attestation subject digest is present", "Trust material for the signer is available and within its validity window" ], "effects": [ "Failure blocks or quarantines admission according to policy", "Verification result, policy version and verification instant are recorded for audit" ], "source_refs": [ "SRC-006", "SRC-007", "SRC-017" ] }, { "id": "fn-evaluate-vulnerability-exposure", "name": "Evaluate vulnerability exposure", "description": "Compute whether a specific version falls within published advisory ranges and record the verdict with its evidence.", "inputs": [ "versioned component coordinate", "advisory records with ranges and events", "ecosystem version ordering function" ], "outputs": [ "per-advisory affectedness verdict", "matched range and events", "assessment instant and advisory snapshot reference" ], "preconditions": [ "Advisory source set and their snapshot times are known", "A version ordering function exists for the declared version scheme" ], "effects": [ "Absence of a match is recorded as scanned-and-not-matched, never as proven absence", "Verdicts are appended with their evidence so they can be recomputed and contested" ], "source_refs": [ "SRC-008", "SRC-005" ] }, { "id": "fn-determine-license-obligations", "name": "Determine licence position and obligations", "description": "Parse declared licensing, record a concluded expression and derive the redistribution obligations that follow.", "inputs": [ "declared licence expression and licence files", "usage and linkage context", "obligation rule set" ], "outputs": [ "canonical concluded licence expression", "selected disjunct where a choice exists", "derived obligation list with owners" ], "preconditions": [ "Licence text or expression is available, or an explicit no-assertion value is recorded", "Reviewing agent is identified and authorised" ], "effects": [ "Determination is versioned with its rationale and approver rather than overwritten", "Unparseable or ambiguous expressions are escalated and block redistribution until resolved" ], "source_refs": [ "SRC-009", "SRC-001", "SRC-005" ] }, { "id": "fn-classify-release-state", "name": "Classify release lifecycle state", "description": "Read the registry of record and classify the current state of a release, recording transitions as events.", "inputs": [ "versioned component coordinate", "registry state response", "registry lifecycle policy" ], "outputs": [ "current state term", "transition event with reason and event time", "resolver behaviour directive for that state" ], "preconditions": [ "Registry of record is designated for the coordinate", "Registry lifecycle vocabulary is mapped to the model's state terms" ], "effects": [ "Transitions are appended to the state log; states are never edited in place", "Yanked and deprecated states propagate a selection directive to resolvers" ], "source_refs": [ "SRC-014", "SRC-015", "SRC-001" ] }, { "id": "fn-assess-adoption-readiness", "name": "Assess adoption readiness", "description": "Combine identity confidence, provenance verification, licence position, exposure and health signals into a gated adoption decision.", "inputs": [ "identification evidence and confidence", "provenance verification result", "licence determination", "exposure verdicts", "health check results" ], "outputs": [ "adoption decision", "gating criteria failed if any", "decision owner, rationale and review date" ], "preconditions": [ "Each input carries its own observation time and staleness status", "Gating thresholds are defined and versioned" ], "effects": [ "Decision records the exact inputs and their versions so it can be re-executed", "Stale inputs force re-measurement rather than silent reuse" ], "source_refs": [ "SRC-016", "SRC-017", "SRC-010", "SRC-008" ] }, { "id": "fn-project-component-record", "name": "Project component record to an exchange format", "description": "Emit the component record in a target exchange format and report which fields were lost or synthesised.", "inputs": [ "component record", "target format and version", "projection profile" ], "outputs": [ "format-specific representation", "lossiness report", "round-trip validation result" ], "preconditions": [ "A versioned field mapping exists for the target format", "Mandatory target fields either have values or an approved no-assertion value" ], "effects": [ "No conformance claim is emitted without a stored validation result", "Synthesised values are flagged in the output and in the lossiness report" ], "source_refs": [ "SRC-001", "SRC-005", "SRC-018", "SRC-002" ] }, { "id": "fn-record-assertion", "name": "Record an assertion about a component", "description": "Append a claim about the component with its asserting agent, source, evidence and the distinct event, observation and ingestion times.", "inputs": [ "subject identifier", "claim predicate and value", "source document reference", "asserting agent" ], "outputs": [ "ledger entry identifier", "stored claim with three time values", "conflict flag where an existing claim disagrees" ], "preconditions": [ "Subject resolves to a known component or release identity", "Observation time is available and expressible with an explicit offset" ], "effects": [ "Existing claims are superseded, not overwritten; prior values remain queryable", "Conflicts are surfaced for reconciliation instead of being silently resolved" ], "source_refs": [ "SRC-008", "SRC-001", "SRC-006" ] }, { "id": "fn-compare-versions", "name": "Compare package versions", "description": "Order two version strings under a declared scheme and report precedence, including pre-release handling.", "inputs": [ "Two version strings", "Version scheme code", "Optional PURL type for ecosystem rules" ], "outputs": [ "Precedence result", "Whether they are comparable under the scheme", "Notes on build metadata being ignored for SemVer precedence" ], "preconditions": [ "A version scheme is declared or defaulted with an explicit warning" ], "effects": [ "Pure comparison with no registry mutation" ], "source_refs": [ "SRC-028", "SRC-029", "SRC-003" ] }, { "id": "fn-map-identifiers", "name": "Map external identifiers", "description": "Translate among PURL, native coordinates, CPE and SWID without claiming that a successful map is identity equality.", "inputs": [ "Source identifier and type", "Target identifier family" ], "outputs": [ "Mapped identifier if rules exist", "Lossiness and conflict notes", "Explicit non-map when CPE class cannot select a unique PURL" ], "preconditions": [ "Source identifier is syntactically valid" ], "effects": [ "Writes or updates the identifier alignment map when a mapping is stored", "Must record conflicts rather than overwrite" ], "source_refs": [ "SRC-020", "SRC-024", "SRC-025", "SRC-026" ] } ], "composition": [ { "target": "WM-SFT-001 Software Product / Service", "relation": "COMPOSE", "purpose": "A software product or service is composed of component or package releases; the product model owns architecture, market framing and operation, this model owns the reusable versioned unit. SPDX models both as Package instances, so the distinction is carried by this edge rather than by class.", "required": true, "source_refs": [ "SRC-001", "SRC-018", "SRC-005" ] }, { "target": "WM-SFT-012 Software Bill of Materials", "relation": "REFERENCE", "purpose": "A package release references the SBOM documents that assert its contents. SPDX defines Sbom as a distinct class, so document structure, completeness and exchange stay in the sibling model while this model keeps the reference and the coverage claim.", "required": false, "source_refs": [ "SRC-018", "SRC-005" ] }, { "target": "Vulnerability / advisory record (OSV, CVE, GHSA)", "relation": "REFERENCE", "purpose": "Affectedness verdicts reference advisory records that carry their own identifiers, aliases, ranges, severities and modification times. This model stores only the resolved verdict for a concrete version plus its evidence.", "required": false, "source_refs": [ "SRC-008" ] }, { "target": "Organisation / Agent (supplier, author, distributor, steward)", "relation": "REFERENCE", "purpose": "Supplier, originator, distributor and steward roles reference agent identities owned elsewhere; the model records the role edge and its assertion basis, never duplicate legal-entity master data.", "required": true, "source_refs": [ "SRC-001", "SRC-005", "SRC-010" ] }, { "target": "Source code repository revision", "relation": "REFERENCE", "purpose": "Links a release to the exact revision claimed to have produced it, keeping repository, branch and review process in the source model.", "required": false, "source_refs": [ "SRC-002", "SRC-006" ] }, { "target": "Build or pipeline run", "relation": "REFERENCE", "purpose": "References the build run whose provenance predicate binds a builder identity and build definition to the artifact's subject digest; the run itself is a separate event entity.", "required": false, "source_refs": [ "SRC-006", "SRC-007" ] }, { "target": "Package URL (purl) identifier scheme, ECMA-427", "relation": "ALIGN", "purpose": "Canonical component identity aligns to the purl syntax and normalization rules as a governed global identifier scheme; alignment is asserted as a mapping, not as conformance.", "required": true, "source_refs": [ "SRC-002", "SRC-003" ] }, { "target": "SPDX License List and licence expression grammar", "relation": "ALIGN", "purpose": "Licence expressions are canonicalized to the SPDX expression grammar with its identifiers, operators and precedence so that determinations are comparable across suppliers.", "required": true, "source_refs": [ "SRC-009" ] }, { "target": "CPE 2.3 product-class naming", "relation": "ALIGN", "purpose": "Aligns package identity to product-class names used for platform enumeration and vulnerability matching, recording the mapping as lossy and directional rather than equivalent.", "required": false, "source_refs": [ "SRC-011" ] }, { "target": "SWID tag / software asset inventory (ISO/IEC 19770-2)", "relation": "ALIGN", "purpose": "Aligns package identity to installed-software identification for asset management, keeping endpoint installation state outside this model.", "required": false, "source_refs": [ "SRC-012" ] }, { "target": "Container image / OCI artifact", "relation": "EXTEND", "purpose": "Extends package identity with content-descriptor addressing for container and OCI-distributed artifacts, where the digest rather than the mutable tag is the identity.", "required": false, "source_refs": [ "SRC-013", "SRC-002" ] }, { "target": "Assertion provenance mixin (asserting agent, source, event and observation time)", "relation": "MIX-IN", "purpose": "Supplies the uniform attribution and time-separation fields applied to every claim in this model so that provenance is not re-implemented per finding.", "required": true, "source_refs": [ "SRC-008", "SRC-001", "SRC-006" ] }, { "target": "Regulatory obligation register (EU Regulation 2024/2847 and equivalents)", "relation": "REFERENCE", "purpose": "References the register of market-specific duties, so support-period, due-diligence and reporting obligations attach to the component without embedding jurisdiction-specific rules in this model.", "required": false, "source_refs": [ "SRC-010", "SRC-019" ] }, { "target": "Secure development process framework (NIST SP 800-218)", "relation": "ALIGN", "purpose": "Aligns the model's verification, archiving and reuse functions to a recognised secure development practice set, recorded as an alignment rather than a conformance claim.", "required": false, "source_refs": [ "SRC-017" ] } ], "serviceLayers": { "dimension": { "owner_package_requirements": [ "The adopting Dimension MUST name exactly one owner package that holds the component register and is accountable for coordinate normalization, duplicate detection and merge decisions.", "The owner package MUST declare a registry of record per purl type, plus the precedence rule applied when an internal and a public registry disagree about the same coordinate.", "The owner package MUST publish the versioned admission policy (digest verification, signature verification, provenance requirements, licence gating) that governs whether a release may be adopted.", "The owner package MUST retain assertion provenance for every externally sourced fact, including source document reference, asserting agent and observation time, and MUST NOT ingest facts that lack an observation time.", "The owner package MUST maintain namespace reservations for internal components and monitor for public coordinates that collide with them." ], "namespace_guidance": "Partition primarily by purl type, then by ecosystem namespace, mirroring the registry of record rather than internal team structure. Internal-only components use a reserved Dimension namespace that MUST NOT collide with any public purl type or public registry namespace, and resolution MUST prefer the registry of record so that a newly published public coordinate cannot substitute for an internal one. Never encode versions, dates, environments or deployment tiers into namespaces; those are attributes, not identity. Aliases from legacy internal names to canonical purls are recorded explicitly and retained after migration.", "registry_links": [ "purl type registry and type definitions governing valid type tokens and their normalization rules", "SPDX License List identifiers and exceptions used to canonicalize licence expressions", "OSV ecosystem identifiers used to align advisory package coordinates with purl types", "CPE dictionary entries used for product-class alignment and vulnerability matching", "Vercy model relations register at planning/VERCY-MODEL-RELATIONS.csv for parent, sibling and alignment edges" ] }, "canon_and_patch": { "canonicalization_rules": [ "Canonical component identity is the normalized purl: lowercase type, type-specific case rules for namespace and name, percent-encoded segments per the specification, and the version retained as an opaque percent-encoded string.", "Qualifiers are sorted by key, keys lowercased, and empty-valued qualifiers removed before comparison; the subpath is normalized by stripping leading and trailing separators and discarding empty, dot and double-dot segments.", "Artifact identity is canonicalized as a lowercase algorithm:encoded digest; the digest, not a tag, channel or file name, is the comparison key, because tags are mutable while digests are content-addressed.", "Version comparison uses the declared version scheme's own precedence function; where a scheme defines build metadata as ignored for precedence, that rule is applied. No cross-scheme ordering is defined and none MUST be assumed.", "Licence expressions are canonicalized to SPDX expression syntax with consistently cased operators, identifiers preserved as listed, and redundant parentheses removed only where precedence is unchanged.", "All recorded times are canonicalized to RFC 3339 with explicit seconds and an explicit offset before comparison; date-only values remain dates and are never coerced into instants." ], "patch_rules": [ "A released version's content is immutable. Corrections are published as new versions or recorded as new state assertions; the artifact record for a released version is never edited in place.", "Metadata patches are additive assertions carrying asserting agent, source reference, event time and observation time; superseded values are retained and remain queryable rather than overwritten.", "Lifecycle transitions (deprecate, yank, withdraw, remove) are appended as events with reason strings and event times; they never mutate a state field in place.", "A patch that would change an identity-bearing field (type, namespace, name, version, artifact digest) MUST be rejected; the correct action is a new entity plus an explicit alias, merge or supersession edge with a rationale.", "Bulk patches from an upstream feed MUST record the feed identifier, feed snapshot time and a per-record change reason; a feed may not silently delete records." ], "compatibility_rules": [ "Adding an optional field, a new vocabulary term or a new alignment is a minor change. Removing a field, narrowing cardinality, tightening a required flag or changing a canonicalization rule is a breaking change requiring a major version.", "Consumers MUST ignore unrecognized fields and MUST treat unset, null and empty values as equivalent, so that producers on a newer minor version remain readable.", "Extension fields are namespaced by the extending party and MUST NOT shadow specified field names.", "Alignment targets are versioned independently; upgrading an alignment target is breaking for this model only where a previously valid value becomes invalid, and such upgrades require a migration note.", "Deprecated fields are retained for at least one major version with a machine-readable deprecation marker and a documented successor." ] }, "artifact_rules": { "identity_priority": [ "Authoritative master-system identifier: the identifier issued by the registry of record for the component release, that is, the ecosystem registry's own package-and-version record key, or the registry's immutable content digest where the registry is content-addressed. This is always preferred where it exists.", "Governed global identifier or IRI: the canonical purl as standardized in ECMA-427, together with any applicable SPDX Element IRI, CPE name or SWID tag identifier carried as secondary aligned identifiers with recorded mapping confidence.", "UUID or ULID assigned by the adopting Dimension: used only where no master-system identifier and no governed global identifier exists, and always stored alongside the strongest available external identifier so it can later be superseded.", "A version string, release date, build number, tag or file name is never an identifier on its own; a date is explicitly not an identifier." ], "timestamp_rule": "All time values are recorded in RFC 3339 format with explicit seconds and an explicit numeric UTC offset or the Z designator; local times lacking an offset are rejected at ingestion. Event time (built time, release or publication time, deprecation or yank time, signature time, advisory publication time) MUST be recorded separately from observation or ingestion time (when the Dimension retrieved, verified or stored the fact), and both MUST be retained whenever they differ or whenever only one is supplied by the source. Where an upstream specification constrains timestamps to UTC only, the value is stored with the Z offset and the constraint is recorded as an alignment note rather than relaxing this rule. Sub-second precision is preserved when supplied; a date-only value such as a support-period end date is stored as a date and never coerced into an instant.", "serial_naming_rule": "Serial artifacts (release artifact files, state change log entries, assertion ledger entries, disclosure packages, notices revisions, assessment records) are named as the canonical purl without qualifiers, followed by the artifact role, followed by a zero-padded monotonic sequence that is unique per component release and never reused after deletion. The sequence is an ordering device only: it MUST NOT be parsed as a date, a version or a semantic identifier, and it MUST NOT be used to infer elapsed time between entries.", "integrity_rule": "Every stored artifact record carries at least one cryptographic digest expressed as algorithm:encoded using an algorithm on the current accepted list. Bytes retrieved from any source MUST be verified against the recorded digest before use or archiving, and the verification outcome, verifying actor and verification instant are appended to the assertion ledger. A digest mismatch quarantines the artifact and raises an incident; it never causes the recorded digest to be replaced. Where no digest is available from the supplier, the Dimension computes and records its own digest on first retrieval and marks the digest as self-computed rather than supplier-attested." }, "policies": [ "Do not claim conformance to any external specification or regulation without a stored, re-runnable validation result. Alignments are recorded as directional mappings with explicit lossiness; the absence of a validation result is itself recorded as a gap.", "Never treat the absence of a vulnerability record as evidence of absence. Record which advisory sources were consulted, their snapshot times and the scan instant, so that a negative result is interpretable as scanned-and-not-matched.", "Internal namespaces are reserved and resolution MUST prefer the registry of record. A newly appearing public coordinate that collides with a reserved internal namespace blocks resolution pending review.", "Upstream removal never deletes the internal record. Coordinates, digests, licence determinations, provenance and decisions are retained for the full retention period even when the artifact is no longer retrievable upstream.", "Every automated determination that gates adoption (identification, licence conclusion, affectedness verdict, provenance verification, health gating) records the tool, tool version, inputs and thresholds so the decision can be re-executed and contested.", "Secrets, credentials and private key material are never stored in the model; only references to a secret manager entry are recorded, and those references are treated as restricted.", "Released non-snapshot payload immutability: never recycle a version string for different bits.", "Known unknowns in dependency graphs MUST be explicit; absence of an edge is not evidence of independence.", "Identifier mappings are alignments; do not claim CPE, PURL, SWID or SPDX conformance without recorded evidence.", "Namespace transfer or maintainer change requires an authority record and leaves prior versions' originator history intact.", "Private, embargoed or export-controlled packages default to deny on bit download even if metadata is internally visible.", "CISA/NTIA baseline component fields (supplier, name, version, other identifiers, dependency relationship) are treated as completeness targets, not as proof that a given SBOM document is compliant." ], "crud": { "read": [ "Resolution is supported by canonical purl, by artifact digest, by registry-native key and by recorded alias, and always returns the identity together with its current state and assertion provenance.", "Closure queries (direct and transitive dependencies or dependents) MUST state the resolution instant used and whether the closure is complete, partial or contains declared unknowns.", "Reads of licence determinations, affectedness verdicts and health signals return the verdict together with its evidence, asserting agent and staleness status; a bare value is never returned.", "Reads of restricted findings and artifacts are subject to the access rules and are audited." ], "create": [ "A component release record is created only after coordinate normalization and duplicate detection against canonical purl, artifact digest and registry-native key.", "Creation requires at least one identifier from the identity priority list and at least one recorded digest, or an explicit and reasoned no-digest exception approved by the register owner.", "Creation records the asserting agent, source document reference, event time where known and observation time, which is mandatory.", "Creating a release whose coordinate collides with a reserved internal namespace requires explicit review before the record becomes resolvable." ], "update": [ "Identity-bearing fields are immutable. Apparent identity changes are handled as a new record plus an alias, merge or supersession edge with a recorded rationale and approver.", "Non-identity metadata updates append a new assertion; the prior assertion remains queryable with its own times and agent, and no field is silently overwritten.", "Lifecycle state changes are written as append-only events, not as field mutations.", "Bulk updates from an upstream feed record the feed identifier, feed snapshot time and per-record change reason, and are reversible as a unit." ], "delete": [ "Hard deletion of a component release record is prohibited while any product, SBOM, attestation, disclosure or decision references it.", "Upstream removal, unpublishing or withdrawal is modelled as a lifecycle state event with a reason, never as record deletion.", "Deletion is permitted only for records created in error, requires two-person authorisation, and leaves a tombstone recording the reason, the authorising agents and the deletion instant.", "Personal data appearing in author or maintainer fields is subject to erasure and rectification requests and is minimised or pseudonymised in place; the component record itself is retained because deleting it would break supply-chain traceability obligations.", "Artifact bytes may be purged on a shorter schedule than metadata, provided the digest, provenance and decisions are retained for the full retention period." ] }, "roles": [ { "name": "Component Register Owner", "responsibilities": [ "Own coordinate normalization, duplicate detection, alias and merge decisions for the register.", "Designate the registry of record per purl type and maintain namespace reservations.", "Approve no-digest and no-source exceptions and record their rationale and expiry." ] }, { "name": "Supply-Chain Verification Engineer", "responsibilities": [ "Maintain and version the admission policy for digest, signature and provenance verification.", "Operate verification runs and record outcomes, policy version and verification instant.", "Investigate digest mismatches, quarantine affected artifacts and raise incidents." ] }, { "name": "Open Source Licence Reviewer", "responsibilities": [ "Record concluded licence expressions with rationale, evidence and approver, and select disjuncts where a choice exists.", "Derive redistribution obligations per linkage kind and maintain the notices assembly.", "Escalate unlicensed, ambiguous or unasserted cases and hold redistribution until resolved." ] }, { "name": "Vulnerability Response Coordinator", "responsibilities": [ "Maintain the advisory source set with snapshot times and run affectedness evaluations.", "Record exploitability analysis, remediation decisions and time-bounded exceptions with approvers and expiry.", "Track regulatory reporting deadlines from the triggering event and evidence that notifications were made." ] }, { "name": "Registry and Distribution Operator", "responsibilities": [ "Operate retrieval endpoints, mirrors and internal archives and guarantee continuity after upstream removal.", "Enforce namespace precedence in resolver configuration and alert on colliding public coordinates.", "Apply retention and purge schedules for artifact bytes distinctly from metadata retention." ] }, { "name": "Compliance and Regulatory Officer", "responsibilities": [ "Maintain the market-specific obligation register and the support-period declarations that reference components.", "Approve disclosure packages, redactions and their legal bases, and record recipient entitlements and expiry.", "Review conformance and alignment claims and reject any not backed by a stored validation result." ] } ], "access": { "default_rule": "Component identity, version, licence determination, lifecycle state and non-embargoed exposure verdicts are readable by any authenticated internal consumer of the Dimension. Artifact bytes, retrieval credentials and secret references, unredacted internal source links, embargoed vulnerability analysis, commercially confidential supplier terms and internal-only component records are restricted to named roles by explicit grant.", "scopes": [ "bundle", "layer", "finding", "artifact" ], "exceptions": [ "Embargoed vulnerability analysis for a component is restricted to the vulnerability response role and named delegates until coordinated disclosure, after which it reverts to the default rule.", "Commercially confidential supplier terms and internal-only components are withheld from external disclosure packages, with a recorded redaction basis and approving agent.", "Retrieval credentials, signing keys and trust material are never exposed through the model; only secret manager entry references are stored and those references are restricted.", "Regulator, auditor or customer access may be granted at bundle or finding scope under a named legal basis with a recorded expiry date and automatic revocation on expiry.", "Personal data in author and maintainer fields is minimised by default and exposed only where a legitimate purpose is recorded.", "Embargoed pre-releases visible only to named maintainer and owner roles", "Private-feed packages never exported through public interfaces", "Legal hold that blocks yank deletion despite maintainer request", "Export-control or license-restricted binaries whose metadata may be listed without enabling download" ], "audit_requirements": [ "Every read of a restricted finding or artifact records the actor, scope, stated purpose and time in RFC 3339 with an explicit offset.", "Every lifecycle transition, licence conclusion, verification result, remediation decision and exception grant is written to an immutable log with the authorising agent and both event and observation times.", "Every access grant, redaction and disclosure issuance records its legal basis, recipient, expiry and the approving role.", "Access grants are reviewed at a defined interval and on expiry; lapsed grants are revoked automatically and the revocation is logged.", "Audit logs are retained at least as long as the component records they describe and are themselves integrity-protected.", "Log resolve, publish, verify, yank and identifier-map writes with actor, event time and observation time.", "Retain integrity verification outcomes even when the archive is later deleted.", "Audit namespace-transfer and master-identifier decisions." ] }, "agents_bootstrap": { "filename": "AGENTS.md", "required_fields": [ "Name", "Type", "Specification URL", "Storage type URL", "Interface URL", "Processes URL", "Model ID", "Registry ID", "Model version", "Owner or maintainer" ], "read_order": [ "Read AGENTS.md first and resolve every required field before any other action; a missing Specification, Storage type, Interface or Processes URL blocks operation.", "Read the Specification URL to load the model semantics, identity priority, canonicalization and timestamp rules.", "Read the Storage type URL to learn how the semantics are projected into the concrete store, whether that is a document store, a Git repository, a relational database or a message interface.", "Read the Interface URL to learn the available operations, authentication and access scopes before attempting any read or write.", "Read the Processes URL to learn the governance workflows for creation, verification, licence determination, lifecycle transitions, exceptions and deletion.", "Only then perform work, recording asserting agent, event time and observation time for every claim written." ] } }, "coverage": { "claim": "Merged context for a versioned distributable software component/package: project- and release-level identity with cross-scheme identifier alignment and content addressing, version designation, declared and resolved composition, pedigree, supply roles, source and build provenance with signature admission, licence determination and redistribution obligations, release lifecycle and support window, version-level vulnerability affectedness and remediation, distribution channel, availability and retention, plus assertion provenance and format projection — with component type/purpose classification and the SBOM reference edge added from grok. Grounded in SPDX 3.0.1, purl/ECMA-427, CycloneDX 1.6, SemVer 2.0.0, OSV, SLSA v1.2, in-toto, OCI descriptors, CPE 2.3, SWID, OpenSSF Scorecard, PEP 592, npm policy, NIST SP 800-218 and the EU CRA summary. Not a claim of universal completeness or of conformance to any single SBOM standard; ecosystem-specific resolution semantics remain unmodelled.", "confidence": "medium", "checklist": [ { "dimension": "identity", "status": "covered", "notes": "Coordinate identity, cross-scheme alignment and content addressing are separated into three findings, with identity priority placing the registry-of-record identifier first and purl second. Verified against the purl syntax and required components, SPDX Package properties, CycloneDX required type and name, and OCI digest content addressability." }, { "dimension": "lifecycle", "status": "covered", "notes": "Release state, permitted transitions and support windows are grounded in PEP 592 yank semantics (installers must ignore yanked releases unless explicitly pinned), the npm unpublish regime with its 72-hour window and permanent version-reuse prohibition, and SPDX builtTime, releaseTime, validUntilTime and supportLevel." }, { "dimension": "relationships", "status": "covered", "notes": "Declared constraints, resolved closures, contained content and pedigree are modelled as four distinct relation kinds, supported by CycloneDX dependency scope and pedigree, SLSA resolvedDependencies, and SPDX file and snippet classes. The dependency edge scope vocabulary is taken from CycloneDX because the SPDX dependency relationship page could not be retrieved." }, { "dimension": "temporal", "status": "covered", "notes": "Event, observation and ingestion times are separated in the timestamp rule, the assertion provenance finding and multiple data elements. Grounded in SLSA startedOn and finishedOn, OSV published, modified and withdrawn, and SPDX builtTime, releaseTime and validUntilTime." }, { "dimension": "provenance", "status": "covered", "notes": "Two distinct senses are modelled and kept apart: supply-chain provenance (supplier roles, source revision, build attestation, signature) and record provenance (who asserted a fact, from which source, when). Grounded in SLSA buildDefinition and runDetails, in-toto Statement subject digest requirement, and SPDX originatedBy and suppliedBy." }, { "dimension": "ownership", "status": "covered", "notes": "Supplier, originator, distributor and steward roles are distinguished, with security-response accountability and steward status treated separately. Grounded in SPDX originatedBy and suppliedBy, CycloneDX supplier, manufacturer, authors and publisher, and the CRA open-source steward provisions." }, { "dimension": "validation", "status": "covered", "notes": "Digest verification before consumption, attestation subject-digest matching, affectedness recomputation, licence expression parsing and projection round-trip testing are each modelled with an explicit acceptance criterion and a stored result. Grounded in the OCI verification statement, in-toto digest matching and NIST SP 800-218." }, { "dimension": "access", "status": "covered", "notes": "Default rule, four scopes, five exceptions and five audit requirements are specified, including embargoed advisory analysis, redaction basis for confidential components and secret-reference-only storage. Regulatory disclosure entitlement is modelled as a finding with legal basis and expiry." }, { "dimension": "retention and deletion", "status": "covered", "notes": "Upstream removal is modelled as a lifecycle event rather than deletion; hard deletion is blocked while references exist and requires two-person authorisation with a tombstone. Artifact bytes may be purged on a shorter schedule than metadata. Grounded in the npm unpublish conditions, PEP 592's rationale against deletion, and Semantic Versioning's immutability rule." }, { "dimension": "interoperability", "status": "covered", "notes": "Cross-scheme identifier alignment and format projection are separate findings, each requiring recorded lossiness and a stored validation result before any conformance claim. Grounded in SPDX externalIdentifier and externalRef, CycloneDX cpe, purl, swid, swhid and omniborId fields, and the purl standard qualifiers." }, { "dimension": "classification", "status": "covered", "notes": "Package type, primary and additional purpose, dependency scope, linkage kind, derivation kind and version scheme are all modelled as classifiers with named vocabularies drawn from SPDX SoftwarePurpose and CycloneDX component type and scope." }, { "dimension": "licensing and legal obligations", "status": "covered", "notes": "Declared versus concluded licensing, disjunct selection, attribution and notice obligations, support period and disclosure duties are modelled with the SPDX expression grammar and the CRA summary of legal provisions as the grounding sources." }, { "dimension": "integrity and signing", "status": "covered", "notes": "Digests, accepted algorithm policy, signature envelopes, signer identity, verification-at-time and documented acceptance exceptions are modelled. Grounded in OCI descriptor digest rules and the in-toto requirement that every subject element set a digest." }, { "dimension": "measurement", "status": "covered", "notes": "Project health checks with risk levels and a fixed 0-10 scale, identification confidence and provenance assurance level claims are modelled with tool, version, evaluated revision and measurement instant. Grounded in OpenSSF Scorecard." }, { "dimension": "evidence and confidence", "status": "covered", "notes": "Identification evidence, technique, generation context and confidence are a dedicated finding, and conflicting identifications must be reconciled with the losing claim retained. Grounded in the CycloneDX evidence structure." }, { "dimension": "security", "status": "covered", "notes": "Namespace substitution controls, digest algorithm policy, admission gating, quarantine on mismatch and secret-reference-only storage are specified. Grounded in the OCI verification requirement, OpenSSF Scorecard risk levels and NIST SP 800-218." }, { "dimension": "spatial", "status": "not-applicable", "notes": "Geographic location is not intrinsic to a package. The nearest analogue, retrieval endpoint and mirror location, is modelled under distribution; jurisdiction enters only through the regulatory obligation edge and is deliberately not modelled as a property of the component." }, { "dimension": "privacy", "status": "gap", "notes": "Author and maintainer fields can carry personal data and erasure or rectification requests are addressed in the delete rules, but no primary source was obtained on how registries and SBOM formats should handle personal data of contributors. This is recorded as a gap rather than presented as canonical." } ], "known_omissions": [ "Ecosystem-specific dependency semantics are not enumerated: Cargo features, Maven dependency management and BOM imports, Go minimal version selection, Debian and RPM epochs and Python extras all change resolution behaviour and would need per-type profiles.", "Cryptographic key management, trust roots, transparency log operation and key rotation are referenced but not modelled; they belong to a sibling trust-infrastructure model.", "Machine-learning model and dataset packaging (model cards, data governance, training provenance) is only referenced through the component type vocabulary and is not developed.", "Export control, sanctions screening and country-of-origin restrictions are not modelled; no primary source was obtained during this research and inventing structure would be unsupported.", "The SBOM document lifecycle, its own signing, versioning and distribution are deliberately deferred to WM-SFT-012 and are not duplicated here.", "Cost, contractual and procurement attributes of commercial components are out of scope and would need a separate commercial-terms model.", "Binary similarity and provenance recovery techniques for artifacts with no manifest are acknowledged in the evidence finding but not specified as a method.", "The CISA 2026 Minimum Elements PDF body was not retrieved; field-level 2026 deltas versus NTIA 2021 are therefore not cited as primary text.", "VERS version-range syntax is planned as an Ecma standard in 2026 and is not treated as normative here.", "Ecosystem-specific version grammars beyond SemVer and Maven (PEP 440, Debian Policy epochs, RubyGems, NuGet, Go modules, OCI index, conda, Hex, Yocto) are not fully expanded.", "Registry unpublish windows (npm, crates.io yank, PyPI yank) lack first-party policy citations in this pass.", "EU Cyber Resilience Act component identification duties, NIST SSDF, and sector SBOM profiles are not incorporated.", "Sigstore/Rekor, in-toto and SLSA provenance attestations are omitted as a sibling process model.", "OSGi bundle symbolic-name+version, Java module names, and language-level package names distinct from distribution packages are omitted.", "Private coordinate collisions across disconnected registries (same GAV, different bits) need operational federation rules not specified by the cited standards." ], "conflicts": [ "No universal version ordering exists. Semantic Versioning defines strict precedence with build metadata ignored, while OSV explicitly distinguishes GIT, SEMVER and ECOSYSTEM range types precisely because ecosystem ordering differs. The model therefore refuses a canonical cross-scheme precedence and stores the version as opaque with a declared scheme.", "Version is not universally mandatory. CycloneDX requires only type and name, and SPDX makes packageVersion optional at 0..1, whereas component-inventory practice treats version as a minimum element. The model keeps version optional at project level and required at release level rather than asserting a single rule.", "purl, CPE and SWID answer different questions. purl addresses a downloadable package, CPE names classes of IT products for platform enumeration, and SWID describes installed software for asset management. Mappings between them are lossy and directional; the model records mapping confidence and forbids treating them as equivalent.", "Deletion regimes conflict across registries. npm permits unpublish within 72 hours and under narrow later conditions while permanently forbidding version reuse; PyPI's yank keeps the file installable for explicit pins; Semantic Versioning simply forbids modifying released content. The model normalizes these to lifecycle states plus a registry-specific policy reference rather than assuming one behaviour.", "Timestamp granularity conflicts with this model's rule. SLSA specifies build timestamps in a UTC-only form and OSV requires RFC3339 timestamps ending in Z, whereas the Vercy rule requires an explicit offset or Z. The model stores such values with the Z designator and records the upstream constraint as an alignment note; it does not relax the offset requirement.", "The CRA SBOM clause could not be verified directly. The European Commission summary of legal provisions confirms the vulnerability-handling duty covering components, the manufacturer-determined support period and the 24-hour, 72-hour and 14-day reporting deadlines, but states that the summary does not itself set out an SBOM mandate. The frequently cited Annex I Part II wording on a machine-readable software bill of materials covering at least top-level dependencies is therefore recorded as unverified in this research pass.", "Attempts to retrieve the CISA and NTIA minimum-elements documents returned HTTP 403, so the specific 2025 and 2026 field names (component hash algorithm, component license, tool name, generation context) are not cited as primary support. Where the model uses those concepts they are grounded instead in CycloneDX and SPDX fields.", "CPE identifies abstract product classes, not unique package instantiations or installations (NIST CPE 2.3 versus PURL/SWID).", "SPDX 3.0.1 is a breaking model relative to SPDX 2.3 / ISO/IEC 5962:2021.", "CycloneDX and SPDX make package version optional; CISA/NTIA framing treats component version as a baseline SBOM attribute.", "SemVer 2.0.0 forbids modifying released content; Maven SNAPSHOT versions and mutable container tags intentionally violate that immutability.", "Apache Maven coordinate guidance recommends Semantic Versioning 1.0.0, not 2.0.0.", "SPDX SoftwarePurpose and CycloneDX component type overlap but are not a 1:1 code set; purpose is use-context in SPDX.", "Declared versus concluded licenses may disagree; neither is the legal instrument.", "The same bits may be published under multiple PURLs (mirrors, forks, republished Maven coordinates), so PURL uniqueness is per ecosystem coordinate, not per content.", "CISA 2026 replaces NTIA 2021 minimum elements at guidance level while Framing 2024 remains the detailed attribute discussion; do not claim a single current field table without the 2026 PDF." ], "regional_assumptions": [ "Support-period determination, due-diligence duties and the 24-hour, 72-hour and 14-day reporting deadlines are grounded in EU law and apply to products placed on the EU market; reporting obligations begin 11 September 2026 and general application follows on 11 December 2027. Other jurisdictions are assumed to differ and are not modelled.", "US federal SBOM minimum-element expectations are referenced conceptually but not cited as primary support because the source documents could not be retrieved; any US procurement-driven field list must be re-verified before use.", "Registry lifecycle behaviour is registry-specific, not global. The npm and PyPI regimes cited here are examples of the range of behaviours, and each adopting Dimension must record the actual policy of its own registry of record per purl type.", "Licence identifiers and expressions are jurisdiction-neutral as text, but the enforceability and interpretation of the resulting obligations are jurisdictional and are deliberately delegated to legal review rather than encoded.", "Personal-data handling for maintainer and author fields is assumed to follow the adopting Dimension's own data protection regime; no region-specific rule is encoded.", "US CISA/NTIA SBOM guidance is treated as influential public-authority practice, not as global law.", "English remains the normative language of SPDX.", "Public default registries (Maven Central, npmjs.com, PyPI) are used as examples of master systems; many enterprises use internal registries as the true master.", "ISO SWID and SWHID are international; operational SWID issuance is uneven outside US federal software identification programmes." ], "adversarial_checks": [ "Searched for a normative cross-ecosystem version precedence rule and found none: OSV's separate GIT, SEMVER and ECOSYSTEM range types are direct evidence that ecosystems order versions differently. A single canonical version-ordering finding was therefore rejected as attractive but unsupported.", "Tested whether project identity and release identity can share one entity. They cannot: purl makes version optional, npm forbids reuse of a package@version pair permanently, and advisory ranges bind to versions rather than projects. The model keeps both levels and states which operations bind to which.", "Tested whether SBOM content belongs in this model. SPDX defines Sbom as a class distinct from Package, so SBOM structure and completeness were pushed to WM-SFT-012 and only the reference edge and coverage claim retained, matching the registered REFERENCE relation.", "Looked for a normative requirement that every package carry a digest and found none: SPDX verifiedUsing is 0..* and CycloneDX hashes are optional. The integrity rule is therefore stated as a Dimension policy with a self-computed fallback, not as an external requirement.", "Attempted to verify the CRA Annex I SBOM clause through four separate EUR-Lex URL forms; all returned empty content. Rather than paraphrase from memory, the claim is recorded as an unresolved evidence gap and the regulatory finding was rebuilt around the provisions the Commission summary does verify.", "Attempted to retrieve the CISA and NTIA minimum-elements documents and received HTTP 403 on every attempt, including the 2026 revision. No field names from those documents are cited as primary support; the corresponding concepts are grounded in CycloneDX and SPDX instead.", "Checked whether the SPDX dependency relationship vocabularies could be cited: the SoftwareDependencyRelationship and SoftwareDependencyLinkType pages returned 404 at the expected paths. Dependency scope and linkage are therefore attributed to CycloneDX only, and the SPDX dependency vocabulary is flagged in the relationships checklist note.", "Considered adding a deployment or runtime-instance layer and rejected it: runtime state belongs to a sibling operational model, and including it would have duplicated concepts the registry assigns elsewhere.", "Verified that the SLSA v1.1 provenance page is marked retired and re-sourced the provenance finding from v1.2, avoiding a citation to a superseded specification.", "Mutable container or Git tags presented as versions must lose to digest or SWHID identity, or the record is incomplete.", "Namespace hijack or coordinate reuse after unpublish must not silently attach new bits to an old version string.", "A CPE match must not be treated as proof that this exact package instance is affected.", "Publisher-declared hashes that disagree with ingestion-time hashes must remain visible rather than averaged.", "Dual publication of the same archive under two PURLs must produce two coordinates with a same-content relationship, not a merged identity.", "Missing dependency edges must not be interpreted as an empty graph when completeness is unknown." ] }, "researchAdjudication": { "providerMode": "dual-provider", "activeProviders": [ "claude", "grok" ], "waivedProviders": [], "providerPolicy": {}, "boundaryDecision": { "entry_kind": "entity", "status": "accepted", "rationale": "Both providers independently classify WM-SFT-007 as an entity and both draw the same sibling cuts (WM-SFT-001 product, WM-SFT-012 SBOM document, advisory/CVE record, build run, installed asset). The entity is the distributable unit, carrying two identity levels — project-level coordinate and release-level version — inside one entity rather than being split, because purl makes version optional at project level while advisory ranges, digests and registry immutability bind at release level; the base tested this explicitly and kept both. Vulnerability, build-run, SBOM-document and product content stay out; only the affectedness verdict, the attestation reference plus subject digest, the SBOM reference edge and the composition edge are retained." }, "decisions": [ { "concept": "Base provider selection", "disposition": "claude as base", "rationale": "Claude carries eight source-backed boundary notes naming every adjacent model, an explicit statement of where the model stops, and adversarial checks that tested the hardest boundary calls (project vs release identity, SBOM content, a rejected deployment layer). Grok's boundaries are also clean but its structure collapses access, retention and interoperability into one finding and buries pedigree inside the containment finding, so the base has the clearer complete boundaries independent of size." }, { "concept": "Project-level vs release-level identity", "disposition": "kept as one entity with two levels", "rationale": "purl makes version optional and CycloneDX/SPDX treat version as optional, while npm forbids permanent version reuse and advisory ranges bind to versions. One entity with a stated binding level per operation preserves both facts; splitting into two entities would duplicate coordinates, licensing and supplier roles." }, { "concept": "Component type and software purpose", "disposition": "accepted from grok", "rationale": "Materially missing from base structure despite being asserted as covered in its checklist, and independently grounded in SPDX SoftwarePurpose and the required CycloneDX component type field." }, { "concept": "SBOM reference edge and relationship completeness", "disposition": "accepted from grok", "rationale": "The base promises the reference edge to WM-SFT-012 in scope but never instantiates it; grok supplies the edge, root-element role and completeness assertion without importing SBOM document identity, which stays in the sibling model." }, { "concept": "Registry-native coordinates (Maven GAV, classifier, extension)", "disposition": "rejected as duplicative", "rationale": "Base f-ecosystem-coordinate already covers coordinate address, normalization and namespace authority, and f-release-variant-set covers per-variant identity and selection, which is what classifier and extension discriminate. Maven-specific grammar belongs to the per-ecosystem profiles both providers list as omissions." }, { "concept": "Dedicated Package-URL identity finding", "disposition": "rejected as duplicative", "rationale": "purl type, namespace, name, version, qualifiers and subpath plus normalization are already the substance of base f-ecosystem-coordinate, which cites the SPDX purl annex and the purl introduction. A second node would split one identity concept across two findings." }, { "concept": "Content-addressed identifiers (SWHID, gitoid, OmniBOR)", "disposition": "rejected as structure, citation deferred", "rationale": "Base f-content-address-integrity and f-cross-scheme-identifiers already carry digests, OCI descriptors, SWHID and OmniBOR as asserted schemes. Grok's distinct contribution is the ISO/IEC 18670:2025 citation, which is a source-level addition this plan cannot make and is therefore recorded as a verification item." }, { "concept": "Declared versus recomputed digest divergence", "disposition": "rejected as new node; rule folded into existing findings", "rationale": "Keeping publisher-declared and ingestion-computed digests separately visible is a real requirement, but it is a value-retention and conflict rule that base f-content-address-integrity and f-assertion-provenance already own through their verification and conflicting-assertion questions. A parallel integrity finding would duplicate the digest concept." }, { "concept": "Originator, supplier and publisher parties", "disposition": "rejected as duplicative", "rationale": "Base f-supply-roles covers originator, supplier, distributor, security-response authority and repackager effects; namespace publication authority is covered by q-coordinate-authority and the substitution controls in f-registry-location." }, { "concept": "Grok release lifecycle and support finding", "disposition": "rejected as duplicative", "rationale": "Base f-release-state and f-support-window already carry publication state, permitted transitions, resolver behaviour, builtTime/releaseTime/validUntilTime and support level with stronger registry grounding (PEP 592, npm policy). SWID corpus/primary/patch tag roles are deferred rather than merged." }, { "concept": "Vulnerability affectedness and remediation", "disposition": "retained in base as edge only", "rationale": "Grok excludes vulnerability records entirely; the base keeps only the computed verdict for a concrete version plus its evidence, with the OSV entry and its aliases, ranges and modification times left to the advisory sibling. This is consistent with the accepted boundary and is not a contradiction between providers." }, { "concept": "Build provenance and signature admission", "disposition": "retained in base as reference only", "rationale": "Grok defers SLSA and in-toto to a sibling process model. The base stores the attestation reference, the subject digest match and the admission decision while leaving the build run, builder identity and pipeline configuration out, which keeps the package entity verifiable without absorbing the build model." }, { "concept": "CRA regulatory duties bundle", "disposition": "retained, scoped, and held for verification", "rationale": "Support period, due diligence and reporting deadlines are grounded in the Commission summary, but the frequently cited Annex I machine-readable SBOM clause was never verified and the obligation dates fall immediately after the current date, so the bundle stays with a publication hold on any SBOM-mandate claim." }, { "concept": "Project health and security-practice signals", "disposition": "retained with level caveat", "rationale": "Scorecard results measure the upstream project, not the released artifact, so the finding must remain an adoption-signal edge with tool, version, evaluated revision and measurement instant recorded; it is not an intrinsic property of the release." }, { "concept": "Publish and withdraw release functions", "disposition": "rejected", "rationale": "Grok's fn-publish-release and fn-withdraw-release are registry mutation operations; the base function set is read, verify and derive oriented and already classifies release state and records transitions as events. Adding write operations would extend into registry implementation surface both providers place out of scope." } ], "publicationHolds": [ "Re-verify every accepted source URL as live and re-pin versions before publication, including the SPDX 3.0.1 Package, Software profile, purl annex and licence-expression pages, SLSA v1.2 approved status, the ECMA-427 first edition date, the OSV schema revision and the npm unpublish policy.", "Hold any claim that the Cyber Resilience Act mandates a machine-readable SBOM: the Annex I Part II wording was never retrieved and only the Commission summary provisions (support period, due diligence, 24h/72h/14d reporting) are evidenced. Also re-check the 2026-09-11 reporting and 2027-12-11 application dates against the current legal text before publishing.", "Hold all field-level SBOM minimum-element claims: the base received HTTP 403 for the CISA and NTIA documents and grok cited only the CISA 2026 resource page without retrieving the PDF body, so no 2026 field table may be asserted from either pack.", "Domain-profile validation is incomplete: the model must be exercised against at least Maven, npm, PyPI, Debian/RPM, Go and OCI profiles before publication, since ecosystem-specific resolution, version grammar and unpublish semantics are unmodelled in both packs.", "The SWHID ISO/IEC 18670:2025 adoption and the gitoid/OmniBOR placement rule exist only in the grok pack and are not carried by any accepted base source; verify independently before any content-addressed identity claim is published.", "The privacy dimension is an open gap: no primary source was obtained on how registries and SBOM formats should handle maintainer and author personal data, so no retention or erasure guidance may be published as canonical." ], "deferredResearch": [ "Reconcile the SPDX dependency vocabulary evidence: the base recorded 404s for SoftwareDependencyRelationship and SoftwareDependencyLinkType while grok retrieved SPDX Core RelationshipType (dependsOn, hasOptionalDependency, hasProvidedDependency, hasPrerequisite, hasStaticLink, hasDynamicLink). Confirm the live paths and attach the SPDX vocabulary to the declared-dependency finding, which currently cites CycloneDX only.", "Build per-ecosystem resolution and version-grammar profiles: PEP 440, Debian epochs, Maven SNAPSHOT and classifiers, Go minimal version selection, Cargo features, NuGet, RubyGems, conda and OCI index behaviour, each of which changes ordering and closure semantics.", "Obtain first-party registry lifecycle policies beyond npm and PEP 592 — crates.io yank, PyPI yank, Maven Central immutability and Go module proxy retention — to ground the release-state and retention findings per registry of record.", "Track the VERS version-range syntax standardisation effort and decide whether range expressions become a modelled construct or remain delegated to advisory range types.", "Research export control, sanctions screening and country-of-origin restrictions on component distribution; neither provider obtained a primary source and both list it as an omission.", "Specify the same-content relation for one archive published under multiple purls (mirrors, forks, republished coordinates) so dual publication yields two coordinates linked by digest rather than a merged identity.", "Determine how personal data in maintainer and author fields is to be handled by registries and SBOM exchange formats, closing the privacy gap recorded in the base checklist." ] }, "statistics": { "sources": 32, "bundles": 6, "layers": 13, "findings": 29, "questions": 117, "artifacts": 27, "functions": 12 } }