Data contract
Every dataset, every column, every rule. Generated from the code by
scripts/build-docs-reference.py, so it cannot drift from what the importer
actually accepts.
The authoritative copy is always the running system:
crane import spec --json
Contract version 1.
- What it accepts
- Rules
- Subject types
- Datasets
- definitions
- source_systems
- source_system_links
- source_scopes
- sync_runs
- source_snapshots
- coverage_gaps
- org_units
- parties
- products
- components
- build_workflows
- source_assets
- identities
- external_properties
- product_components
- component_workflows
- product_relationships
- workflow_assets
- subject_assets
- workflow_dependencies
- responsibilities
- aliases
- scope
- build_topology
- distribution
- claims
- scope_rules
- evidence
- exceptions
- findings
- decisions
- actions
- action_dependencies
- state_changes
- verifications
- campaigns
- campaign_subjects
What it accepts
- a directory of CSV files, one per dataset, named
.csv - a single .csv file, named after its dataset
- a single .json file whose top level keys are dataset names and whose values are arrays of row objects
Rules
- Unknown columns are an error, not ignored, so a typo is never silent data loss.
- Only the datasets you provide are touched. Loading distribution.csv alone against an existing database is normal.
- References resolve against rows in the same batch and rows already in the database.
- Everything loads as an observation needing review, never as an approved decision, unless source_kind says otherwise and names an authority.
- Loading is idempotent. The same input twice changes nothing the second time.
- Validation runs over the whole batch before anything is written. Either every row loads or none do.
Subject types
product, component, build_workflow, source_asset.
Datasets
| Dataset | File | What it is |
|---|---|---|
definitions |
definitions.csv |
Vocabulary this deployment uses that the core does not define: a relationship type its catalogue has and CRAne has no term for, a claim kind a feed carries. Registering one gives it a name and a description instead of leaving a bare key nobody can explain. |
source_systems |
source_systems.csv |
A system that holds metadata about the portfolio, and how to link back to it. |
source_system_links |
source_system_links.csv |
Where a subject lives in a source system, per kind of thing that system distinguishes. A catalogue exposing services, products and projects addresses them one path segment apart, and all three arrive here as one subject type. |
source_scopes |
source_scopes.csv |
What a feeder is allowed and configured to look at inside a source system. |
sync_runs |
sync_runs.csv |
One execution of a feeder against one scope, with what it covered. |
source_snapshots |
source_snapshots.csv |
A hashed record that a source looked a particular way at a particular time. |
coverage_gaps |
coverage_gaps.csv |
Something a feeder could not see, recorded so that absence is not read as evidence. |
org_units |
org_units.csv |
The accountability hierarchy. Division is the sub legal entity, organization is director level, team is where products are usually owned. |
parties |
parties.csv |
People, teams, and service principals that can own or be accountable for things. |
products |
products.csv |
A reviewable shipping or distributed software unit. |
components |
components.csv |
A building block that may ship in several products. |
build_workflows |
build_workflows.csv |
A build, release, packaging, signing, or publication definition. |
source_assets |
source_assets.csv |
A repository, package, service record, catalog entry, image, or binary. |
identities |
identities.csv |
The same thing, as known by another system. A subject can hold several identities in one system, and status retires one. |
external_properties |
external_properties.csv |
Typed metadata another system holds about a thing, attached to the identity it holds it under. |
product_components |
product_components.csv |
Which components ship in which products. |
component_workflows |
component_workflows.csv |
Which build workflows produce which components. |
product_relationships |
product_relationships.csv |
Product to product: containment, bundling, succession. |
workflow_assets |
workflow_assets.csv |
What a build workflow reads and what it produces. |
subject_assets |
subject_assets.csv |
Which source asset a product or component actually lives in, builds from, or is catalogued as. |
workflow_dependencies |
workflow_dependencies.csv |
A build that depends on another build. This is the fan in and fan out case. |
responsibilities |
responsibilities.csv |
Who is accountable for what. |
aliases |
aliases.csv |
Other names a subject is known by, so search and matching find it. |
scope |
scope.csv |
Whether a subject is in scope, under one named definition. |
build_topology |
build_topology.csv |
Where code lives and where the build runs. Two different questions. |
distribution |
distribution.csv |
Where something enters and leaves the organization. |
claims |
claims.csv |
Anything else known about a subject: a declared support end date, a disclosure contact, a licence. The general purpose dataset for facts that are not relationships. |
scope_rules |
scope_rules.csv |
One scope judgement covering every subject that matches its criteria. |
evidence |
evidence.csv |
Pointers to evidence. The file itself is never copied into the database. |
exceptions |
exceptions.csv |
Queues and checks somebody has decided do not apply to a subject. |
findings |
findings.csv |
Something wrong with a subject, and where it got to. |
decisions |
decisions.csv |
A recorded human judgement: what was decided, by whose authority, and why. |
actions |
actions.csv |
Work somebody owes, with an owner and a due date. |
action_dependencies |
action_dependencies.csv |
An action that cannot start until another finishes. |
state_changes |
state_changes.csv |
A field on a subject changing value, with when and why. |
verifications |
verifications.csv |
Somebody checked that a finding was really resolved, or an action really done. |
campaigns |
campaigns.csv |
A bounded audit: one lens, one obligation, one date range, one frozen population. |
campaign_subjects |
campaign_subjects.csv |
Which subjects a campaign counts, and which it deliberately does not. |
definitions
Vocabulary this deployment uses that the core does not define: a relationship type its catalogue has and CRAne has no term for, a claim kind a feed carries. Registering one gives it a name and a description instead of leaving a bare key nobody can explain.
File: definitions.csv. Natural key: namespace, definition_class, key.
| Column | Required | Kind | Meaning |
|---|---|---|---|
definition_class |
yes | text | Which vocabulary this key belongs to. Closed: a class nothing reads would be a registry entry no part of the system consults. One of: asset_type, channel_type, check_key, claim_kind, decision_type, environment, evidence_kind, obligation, org_level, platform_type, relationship_type, subject_type. |
key |
yes | text | The value as it appears in the data, for example ‘associated_with’. Written exactly as rows carry it. |
display_name |
text | What to call it on screen. The reason to register at all: without one a page can only show the raw key. Optional so a later row can correct a description or a status without restating the name – blank leaves whatever is recorded alone, and on a first declaration falls back to the key. | |
description |
text | What it means in the source system. This is the field that answers ‘what was this value supposed to mean’ a year later. | |
namespace |
text | Whose vocabulary this is. Defaults to ‘local’. ‘crane.core’ is reserved for what ships. Defaults to local. |
|
status |
text | Retired keeps the row so existing data stays explainable, and stops the key being offered for anything new. One of: active, retired. Defaults to active. |
source_systems
A system that holds metadata about the portfolio, and how to link back to it.
File: source_systems.csv. Natural key: key.
| Column | Required | Kind | Meaning |
|---|---|---|---|
key |
yes | text | Short stable identifier, for example ‘metadataservice’. This is what the source_system column on other datasets refers to. |
display_name |
yes | text | What to call it on screen, for example ‘Metadata service’. |
link_template |
text | URL pattern with {id}, {key} or {type} substituted from the external identity, for example https://metadataservice.internal/#/Service/{id}. | |
link_label |
text | Text for the link. Defaults to ‘Open in |
|
connector_type |
text | Defaults to crane.core/declared. |
|
status |
text | One of: active, archived. Defaults to active. |
source_system_links
Where a subject lives in a source system, per kind of thing that system distinguishes. A catalogue exposing services, products and projects addresses them one path segment apart, and all three arrive here as one subject type.
File: source_system_links.csv. Natural key: source_system, subject_type, object_type.
Leaving object_type blank is a value rather than an absence: two rows that both leave it out name the same thing and the second is refused as a duplicate. Repeating another column’s value there is a different identity, not the same one written out.
| Column | Required | Kind | Meaning |
|---|---|---|---|
source_system |
yes | text | |
subject_type |
yes | text | Which kind of thing here the pattern addresses. One of: product, component, build_workflow, source_asset, party. |
object_type |
text | Which kind of thing there. Blank is the pattern for any kind, which is what a system addressing everything alike needs. | |
url_template |
text | http or https, containing {id}, {key} or {type}. Blank means this system has no addressable page for that kind, which is a real answer and not a gap. | |
label |
text | Link text. Defaults to ‘Open in |
source_scopes
What a feeder is allowed and configured to look at inside a source system.
File: source_scopes.csv. Natural key: source_system, scope_key.
| Column | Required | Kind | Meaning |
|---|---|---|---|
source_system |
yes | text | |
scope_key |
yes | text | The scope’s identifier in that system: an organization, a project, a folder, a query. |
display_name |
text | ||
permissions_json |
text | What the credential could actually see, as JSON. A gap between this and the scope is a coverage gap, not an empty result. | |
filters_json |
text | Any filter narrowing the scope, as JSON. | |
rate_limit_json |
text | What the source imposed, as JSON. | |
enabled |
bool | Defaults to True. |
sync_runs
One execution of a feeder against one scope, with what it covered.
File: sync_runs.csv. Natural key: source_system, scope_key, started_at.
| Column | Required | Kind | Meaning |
|---|---|---|---|
source_system |
yes | text | |
scope_key |
yes | text | The scope this run read. Load source_scopes first. |
started_at |
yes | date | When the run began. Part of the key, because a scope is synchronized repeatedly and each run is its own record. |
status |
text | One of: running, succeeded, partial, failed, cancelled. Defaults to running. |
|
cursor |
text | Where the feeder got to, for resuming. | |
watermark |
text | The high water mark it read up to. | |
ended_at |
date | ||
counts_json |
text | What it saw and wrote, as JSON. | |
coverage_status |
text | Whether the run covered the scope, in the feeder’s own terms. | |
partial_failures_json |
text | What failed inside a run that otherwise worked, as JSON. A ‘partial’ status with nothing here is a run nobody can act on. |
source_snapshots
A hashed record that a source looked a particular way at a particular time.
File: source_snapshots.csv. Natural key: source_system, captured_at, content_hash.
| Column | Required | Kind | Meaning |
|---|---|---|---|
source_system |
yes | text | |
captured_at |
yes | date | |
content_hash |
yes | text | Hash of what was captured. What makes the snapshot evidence rather than an assertion that a capture happened. |
scope_key |
text | The scope captured, if the snapshot belongs to one. | |
sync_started_at |
date | The run that captured it, named by its started_at. Needs scope_key too, since that is how a run is identified. | |
object_count |
number | ||
uri |
text | Where the captured content is kept, if it was kept. |
coverage_gaps
Something a feeder could not see, recorded so that absence is not read as evidence.
File: coverage_gaps.csv. Natural key: source_system, scope_key, reason, detected_at.
| Column | Required | Kind | Meaning |
|---|---|---|---|
source_system |
yes | text | |
scope_key |
yes | text | |
reason |
yes | text | Why it could not be seen: permission denied, rate limited, timed out, unsupported object type. |
detected_at |
yes | date | Part of the key, so the same gap recurring is a history rather than one row that keeps being rewritten. |
sync_started_at |
date | The run that hit the gap, named by its started_at. | |
detail |
text | What specifically was missed. | |
remediation |
text | What would fix it, if that is known. | |
resolved_at |
date | Set when the gap closes. A resolved gap stays as history rather than being deleted. |
org_units
The accountability hierarchy. Division is the sub legal entity, organization is director level, team is where products are usually owned.
File: org_units.csv. Natural key: name, level.
| Column | Required | Kind | Meaning |
|---|---|---|---|
name |
yes | text | Unique within its level. |
level |
yes | text | One of: company, division, organization, team. |
parent_name |
text | Name of the unit one level up. Empty for the top. | |
email |
text | Distribution list or contact address. |
parties
People, teams, and service principals that can own or be accountable for things.
File: parties.csv. Natural key: display_name.
| Column | Required | Kind | Meaning |
|---|---|---|---|
display_name |
yes | text | |
party_type |
yes | text | One of: person, team, service, organization. |
email |
text | ||
external_ref |
text | Identifier in the source directory. | |
status |
text | One of: active, archived. Defaults to active. |
products
A reviewable shipping or distributed software unit.
File: products.csv. Natural key: slug.
| Column | Required | Kind | Meaning |
|---|---|---|---|
slug |
yes | text | Stable local identifier, unique per tenant. |
canonical_name |
yes | text | |
lifecycle |
text | Known values: development, released, maintenance, eol, withdrawn, unknown, active, retired, deprecated. Others are accepted and recorded as a finding for a person to look at. Defaults to unknown. |
|
description |
text | ||
implementation |
text | How the product is made, which decides what a build is required of. code_bearing: built from source, so the product must reach a build. logical_bundle: an offering, SKU or rollup made of other products; build requirements apply to what it contains. externally_built: a supplier builds it; no build of ours is expected. manual_process: assembled by hand; no build is expected. Leave empty when nobody knows: an unclassified product is listed for review rather than reported as missing a pipeline. Recorded as a manual product.implementation claim, which a person’s decision outranks. One of: code_bearing, logical_bundle, externally_built, manual_process. |
|
source_system |
text | Which system this row came from, for example ‘project-catalog’. Load the same product from two exports with different values here and it becomes corroborated rather than single sourced. | |
external_id |
text | This product’s identifier in that system. What turns a link_template into a link back to the entry. |
components
A building block that may ship in several products.
File: components.csv. Natural key: slug.
| Column | Required | Kind | Meaning |
|---|---|---|---|
slug |
yes | text | |
canonical_name |
yes | text | |
lifecycle |
text | Known values: development, released, maintenance, eol, withdrawn, unknown, active, retired, deprecated. Others are accepted and recorded as a finding for a person to look at. Defaults to unknown. |
|
description |
text | ||
is_open_source |
bool | Set true for a third party component consumed from outside. | |
purl |
text | Package URL, if the component is a published package. | |
source_system |
text | Which system this row came from. | |
external_id |
text | This component’s identifier in that system. |
build_workflows
A build, release, packaging, signing, or publication definition.
File: build_workflows.csv. Natural key: slug.
| Column | Required | Kind | Meaning |
|---|---|---|---|
slug |
yes | text | |
canonical_name |
yes | text | |
source_system |
text | Key of a source_system row, created if absent. | |
external_id |
text | This pipeline’s identifier in that system. Clicking through to the catalogue entry is how a failing pipeline gets fixed. | |
platform_type |
text | What runs the build. Open vocabulary: a platform not listed here is accepted and shown as given. Known values: github_actions, gitlab_ci, jenkins, azure_pipelines, aws_codebuild, google_cloud_build, bitbucket_pipelines, teamcity, bamboo, circleci, buildkite, tekton, argo_workflows, drone, concourse, travis_ci, make_or_script, manual, vendor_external, unknown. Others are accepted and recorded as a finding for a person to look at. |
|
platform_locator |
text | Where the definition lives: a Jenkins job URL, a workflow file path, an Azure DevOps pipeline id. | |
environment |
text | What the build is for. A product with four pipelines and no production one is a different situation from one with none. Known values: production, staging, testing, development, unknown. Others are accepted and recorded as a finding for a person to look at. |
|
last_run_status |
text | Result of the most recent run. Overwritten each time, and never on its own a reason a compliance score moves. One of: success, unstable, failed, cancelled, running, never_run. |
|
last_run_at |
date | When that run finished. | |
last_run_url |
text | Link to the run, so a red build is one click from the log that explains it. | |
lifecycle |
text | Known values: development, released, maintenance, eol, withdrawn, unknown, active, retired, deprecated. Others are accepted and recorded as a finding for a person to look at. Defaults to unknown. |
|
description |
text |
source_assets
A repository, package, service record, catalog entry, image, or binary.
File: source_assets.csv. Natural key: canonical_locator.
| Column | Required | Kind | Meaning |
|---|---|---|---|
canonical_locator |
yes | text | URL, purl, or path. Unique. |
asset_type |
yes | text | Known values: repository, package, service, catalog_entry, container_image, binary_artifact, release_asset, package_feed. Others are accepted and recorded as a finding for a person to look at. |
display_name |
text | ||
visibility |
text | One of: public, internal, restricted, unknown. Defaults to unknown. |
identities
The same thing, as known by another system. A subject can hold several identities in one system, and status retires one.
File: identities.csv. Natural key: subject_type, subject_slug, source_system, object_type, external_id.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | The subject’s slug here. |
source_system |
yes | text | Which system knows it. |
external_id |
yes | text | Its identifier there. |
external_key |
text | A second identifier, such as a job name or path, for templates that use {key}. | |
display_name |
text | What it is called there, which is often not what it is called here. | |
locator |
text | Full URL for this one object. Wins over the system’s link template. | |
object_type |
text | What kind of object it is there. Defaults to the subject type, and is part of the natural key either way. | |
status |
text | What became of it. Setting this is how a feeder retires an identity, and it is the only way: a row absent from a later feed means nothing was said about it, never that it is gone. One of: active, missing, inaccessible, deleted, unknown. Defaults to active. |
external_properties
Typed metadata another system holds about a thing, attached to the identity it holds it under.
File: external_properties.csv. Natural key: source_system, object_type, external_id, property_name, captured_at.
| Column | Required | Kind | Meaning |
|---|---|---|---|
source_system |
yes | text | Which system this came from. |
object_type |
yes | text | The object type of the identity to attach to, as on identities. |
external_id |
yes | text | The identifier of the identity to attach to, as on identities. |
property_name |
yes | text | What the property is called there. Kept verbatim, because renaming it loses the ability to ask the source about it. |
value_type |
yes | text | Which typed column the value lands in. One of: string, number, boolean, date, json. |
value |
yes | text | The value itself, written as text and coerced by value_type. A ‘json’ value must parse. |
captured_at |
yes | date | When the source held this value. Part of the key, so a property that changes over time keeps its history rather than overwriting itself. |
scope_key |
text | With sync_started_at, the run that observed this value. Both are needed, because that pair is how a run is identified. | |
sync_started_at |
date | The observing run’s started_at. Optional: a value a person recorded by hand did not come from a run. |
product_components
Which components ship in which products.
File: product_components.csv. Natural key: product_slug, component_slug, relationship_type.
| Column | Required | Kind | Meaning |
|---|---|---|---|
product_slug |
yes | text | |
component_slug |
yes | text | |
relationship_type |
text | Known values: contains, bundles. Others are accepted and recorded as a finding for a person to look at. Defaults to contains. |
|
confidence |
number | 0.0 to 1.0. | |
source_kind |
text | One of: imported, inferred, manual, approved. Defaults to imported. |
|
review_status |
text | approved means somebody confirmed the relationship is true of the organization, not just asserted by a source. One of: unreviewed, approved. Defaults to unreviewed. |
|
effective_to |
date | When the relationship stopped holding. Set this rather than omitting the row from a later feed: an absent row means nothing was said, never that the relationship ended. An ended relationship leaves the current graph and stays in the record, and travels in a bundle exported with history. | |
dependency_depth |
number | 1 for a direct dependency, deeper for what an SBOM pulled in behind it. Empty reads as direct. | |
note |
text |
component_workflows
Which build workflows produce which components.
File: component_workflows.csv. Natural key: component_slug, workflow_slug, relationship_type.
| Column | Required | Kind | Meaning |
|---|---|---|---|
component_slug |
yes | text | |
workflow_slug |
yes | text | |
relationship_type |
text | Known values: builds, signs, publishes. Others are accepted and recorded as a finding for a person to look at. Defaults to builds. |
|
confidence |
number | ||
source_kind |
text | One of: imported, inferred, manual, approved. Defaults to imported. |
|
review_status |
text | One of: unreviewed, approved. Defaults to unreviewed. |
|
effective_to |
date | When the relationship stopped holding. Set this rather than omitting the row from a later feed: an absent row means nothing was said, never that the relationship ended. An ended relationship leaves the current graph and stays in the record, and travels in a bundle exported with history. | |
note |
text |
product_relationships
Product to product: containment, bundling, succession.
File: product_relationships.csv. Natural key: from_product_slug, to_product_slug, relationship_type.
| Column | Required | Kind | Meaning |
|---|---|---|---|
from_product_slug |
yes | text | |
to_product_slug |
yes | text | |
relationship_type |
yes | text | Known values: contains, bundles, succeeds, distributes_with. Others are accepted and recorded as a finding for a person to look at. |
confidence |
number | ||
source_kind |
text | One of: imported, inferred, manual, approved. Defaults to imported. |
|
effective_to |
date | When the relationship stopped holding. Set this rather than omitting the row from a later feed: an absent row means nothing was said, never that the relationship ended. An ended relationship leaves the current graph and stays in the record, and travels in a bundle exported with history. | |
note |
text |
workflow_assets
What a build workflow reads and what it produces.
File: workflow_assets.csv. Natural key: workflow_slug, asset_locator, relationship_type.
| Column | Required | Kind | Meaning |
|---|---|---|---|
workflow_slug |
yes | text | |
asset_locator |
yes | text | |
relationship_type |
yes | text | Known values: source, template, output, dependency. Others are accepted and recorded as a finding for a person to look at. |
source_kind |
text | One of: imported, inferred, manual, approved. Defaults to imported. |
|
effective_to |
date | When the relationship stopped holding. Set this rather than omitting the row from a later feed: an absent row means nothing was said, never that the relationship ended. An ended relationship leaves the current graph and stays in the record, and travels in a bundle exported with history. | |
note |
text |
subject_assets
Which source asset a product or component actually lives in, builds from, or is catalogued as.
File: subject_assets.csv. Natural key: subject_type, subject_slug, asset_locator, relationship_type, source_system.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | The subject’s slug here. |
asset_locator |
yes | text | The asset’s canonical locator, from source_assets. |
relationship_type |
yes | text | What the subject does with the asset, in the describing system’s own words. Known values: source, builds, output, contains, depends_on, implements, catalogued_as. Others are accepted and recorded as a finding for a person to look at. |
source_system |
text | Which system asserts this. Part of the key, so two systems disagreeing are two rows rather than one overwriting the other. | |
source_kind |
text | One of: imported, inferred, manual, approved. Defaults to imported. |
|
confidence |
number | 0 to 1, when the asserting system expresses one. | |
review_status |
text | One of: unreviewed, approved, rejected, superseded, conflicted. Defaults to unreviewed. |
|
effective_from |
date | ||
effective_to |
date | When the relationship stopped holding. Set this rather than omitting the row from a later feed: a missing row is not a deletion. | |
note |
text |
workflow_dependencies
A build that depends on another build. This is the fan in and fan out case.
File: workflow_dependencies.csv. Natural key: downstream_slug, upstream_ref.
| Column | Required | Kind | Meaning |
|---|---|---|---|
downstream_slug |
yes | text | |
upstream_slug |
text | Leave empty if the upstream build is not tracked. | |
upstream_ref |
yes | text | The name the source system uses, kept even when unresolved. |
source_kind |
text | One of: imported, inferred, manual, approved. Defaults to imported. |
|
note |
text |
responsibilities
Who is accountable for what.
File: responsibilities.csv. Natural key: subject_type, subject_slug, party, role.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
party |
yes | text | Matches parties.display_name or org_units.name. |
role |
yes | text | Known values: accountable, maintainer, security_contact, owning_organization. Others are accepted and recorded as a finding for a person to look at. |
source_kind |
text | One of: imported, inferred, manual, approved. Defaults to imported. |
|
review_status |
text | One of: unreviewed, approved. Defaults to unreviewed. |
aliases
Other names a subject is known by, so search and matching find it.
File: aliases.csv. Natural key: subject_type, subject_slug, alias, alias_type.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
alias |
yes | text | |
alias_type |
text | Known values: display, legacy, source_label, acronym, name. Others are accepted and recorded as a finding for a person to look at. Defaults to display. |
scope
Whether a subject is in scope, under one named definition.
File: scope.csv. Natural key: subject_type, subject_slug, lens.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
lens |
yes | text | cra.regulatory, commercial, shiproom, legal.oss, or your own. |
status |
yes | text | One of: in_scope, out_of_scope, undecided, not_applicable, disputed. |
rationale |
text | ||
source_kind |
text | One of: observed, normalized, derived, manual, approved. Defaults to manual. |
|
decided_by |
text | Required when source_kind is approved. | |
valid_from |
date |
build_topology
Where code lives and where the build runs. Two different questions.
File: build_topology.csv. Natural key: subject_type, subject_slug.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
code_hosting |
text | One of: internal_git, public_host_public, public_host_private, vendor, none. |
|
build_location |
text | One of: internal_pipeline, public_host_runner, vendor_external, manual, none. |
|
is_signed |
bool | Whether the build signs what it produces. | |
source_kind |
text | One of: observed, normalized, derived, manual, approved. Defaults to observed. |
distribution
Where something enters and leaves the organization.
File: distribution.csv. Natural key: subject_type, subject_slug, direction, channel_type, channel_locator.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
direction |
yes | text | outbound if we make it available, inbound if we consume it. One of: outbound, inbound. |
channel_type |
yes | text | Known values: source_repository, release_asset, nuget, npm, pypi, maven, container_registry, internal_feed, direct_download, oem_partner, embedded_in_device, not_distributed. Others are accepted and recorded as a finding for a person to look at. |
channel_locator |
text | A purl where one exists, else a registry URL. | |
visibility |
text | One of: public, customer, internal, unknown. Defaults to unknown. |
|
is_signed |
bool | Leave empty when unknown. Empty is not the same as false. | |
source_kind |
text | One of: imported, inferred, manual, approved. Defaults to imported. |
|
note |
text |
claims
Anything else known about a subject: a declared support end date, a disclosure contact, a licence. The general purpose dataset for facts that are not relationships.
File: claims.csv. Natural key: subject_type, subject_slug, claim_kind, lens, variant.
Leaving lens, variant blank is a value rather than an absence: two rows that both leave it out name the same thing and the second is refused as a duplicate. Repeating another column’s value there is a different identity, not the same one written out.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
claim_kind |
yes | text | A registered claim kind, or your own namespaced one. Known values: support.end_date, vuln.contact, license.declared, origin.open_source, lifecycle.stage, artifact.purl, sbom.status, distribution.external, code.hosting, build.location, build.signed, product.implementation. Others are accepted and recorded as a finding for a person to look at. |
value |
yes | text | |
value_type |
text | One of: string, number, boolean, date, json. Defaults to string. |
|
lens |
text | Only for claims that mean something under one definition. | |
variant |
text | What tells two claims of one kind about one subject apart, such as the profile a conformance verdict is about. Leave blank where the kind can only mean one thing: blank is its own value, not a shorthand for anything. | |
source_kind |
text | One of: observed, normalized, derived, manual, approved. Defaults to manual. |
|
observed_at |
date | When the source was read. | |
valid_from |
date | ||
valid_to |
date |
scope_rules
One scope judgement covering every subject that matches its criteria.
File: scope_rules.csv. Natural key: subject_type, lens, org_unit, source_system, lifecycle, origin, no_build.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component. |
lens |
yes | text | cra.regulatory, commercial, shiproom, legal.oss, or your own. |
status |
yes | text | One of: in_scope, out_of_scope, undecided, not_applicable, disputed. |
rationale |
yes | text | Has to be true of every subject the rule matches, now and later. |
decided_by |
yes | text | Who answers for it. |
expires_on |
date | YYYY-MM-DD. Omitted means permanent, which is worth asking for. | |
org_unit |
text | A division, organization or team name. | |
source_system |
text | ||
lifecycle |
text | Known values: development, released, maintenance, eol, withdrawn, unknown, active, retired, deprecated. Others are accepted and recorded as a finding for a person to look at. |
|
origin |
text | One of: third_party, internal, unclassified. |
|
no_build |
bool | Components nothing builds. | |
unresolved |
bool | Set by export when the criteria no longer resolve. |
evidence
Pointers to evidence. The file itself is never copied into the database.
File: evidence.csv. Natural key: subject_type, subject_slug, uri.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
kind |
yes | text | Known values: sbom.spdx, sbom.cyclonedx, sbom.manifest, attestation, report, document, closure_record. Others are accepted and recorded as a finding for a person to look at. |
uri |
yes | text | |
content_hash |
text | sha256, if known. | |
media_type |
text | ||
captured_at |
date | ||
state |
text | One of: discovered, retrieved, parsed, validated, current, inaccessible, invalid, stale, superseded, deleted. Defaults to discovered. |
exceptions
Queues and checks somebody has decided do not apply to a subject.
File: exceptions.csv. Natural key: subject_type, subject_slug, queue_key, check_key.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
queue_key |
text | An attention queue key. One of queue_key or check_key, never both. | |
check_key |
text | A check inside an obligation policy. | |
reason |
yes | text | At least eight characters. The sentence somebody reads in a year when they ask why this was excused. |
granted_by |
text | Who granted it. Recorded on the decision. | |
expires_on |
date | Empty means permanent, which is how a portfolio drifts while the dashboard stays green; prefer a date. |
findings
Something wrong with a subject, and where it got to.
File: findings.csv. Natural key: subject_type, subject_slug, code, variant.
Leaving variant blank is a value rather than an absence: two rows that both leave it out name the same thing and the second is refused as a duplicate. Repeating another column’s value there is a different identity, not the same one written out.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
code |
yes | text | What kind of problem it is. Stable, so the same problem on two subjects is countable. |
variant |
text | What tells two findings of one code on one subject apart, such as the profile a conformance check measured against. Leave blank where the code can only mean one thing. Blank is its own identity, not a shorthand for anything: a row that repeats the code here is a different finding from one that leaves it out. | |
title |
yes | text | What is wrong, in one line. |
severity |
text | One of: info, low, medium, high, critical. Defaults to medium. |
|
status |
text | Where it got to. A migration brings findings that were triaged or closed years ago, and importing those as open would reopen work somebody already did. One of: open, triaged, assigned, in_progress, resolved, verified, closed, blocked, accepted, duplicate, not_applicable. Defaults to open. |
|
detail |
text | ||
detected_at |
date | Defaults to now if not supplied. | |
closed_at |
date | ||
confidence |
number | 0 to 1, when the source expresses one. |
decisions
A recorded human judgement: what was decided, by whose authority, and why.
File: decisions.csv. Natural key: subject_type, subject_slug, decision_type, recorded_at.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
decision_type |
yes | text | What kind of judgement: scope, mapping, risk acceptance, exception. Known values: scope, mapping, risk_acceptance, exception, lifecycle. Others are accepted and recorded as a finding for a person to look at. |
recorded_at |
yes | date | When the decision was recorded. Part of the key, because a subject is decided about repeatedly and superseding is a new row rather than an edit to the old one. |
rationale |
yes | text | Why. Required by the schema, not by convention: a decision nobody can explain is one nobody can defend. |
status |
text | One of: proposed, pending_authority, approved, rejected, superseded, expired. Defaults to proposed. |
|
authority |
text | The party whose authority this carries, by display name. Required when the status is ‘approved’. | |
citation |
text | Where the authority is recorded: a ticket, a minute, an email. | |
lens |
text | Which definition this decision is made under, for a scope decision. | |
proposed_value_json |
text | What is being decided, as JSON. | |
effective_from |
date | When it started to apply, which is a different question from when it was recorded and is often unknown. | |
effective_to |
date | ||
approved_at |
date |
actions
Work somebody owes, with an owner and a due date.
File: actions.csv. Natural key: subject_type, subject_slug, title.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
title |
yes | text | What has to be done, in one line. |
status |
text | One of: open, accepted, in_progress, blocked, completed, verified. Defaults to open. |
|
owner |
text | Who owes it, by party display name. | |
due_date |
date | ||
description |
text | ||
blocker_reason |
text | Why it cannot proceed. A ‘blocked’ action without one is a status nobody can act on. | |
completed_at |
date | ||
finding_code |
text | The finding this answers, by code on the same subject. | |
finding_variant |
text | Which one, where that subject carries the same code more than once. Matches the finding’s variant column. |
action_dependencies
An action that cannot start until another finishes.
File: action_dependencies.csv. Natural key: subject_type, subject_slug, title, depends_on_subject_type, depends_on_subject_slug, depends_on_title.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
title |
yes | text | The action that is waiting. |
depends_on_subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
depends_on_subject_slug |
yes | text | |
depends_on_title |
yes | text | The action it waits for. |
note |
text |
state_changes
A field on a subject changing value, with when and why.
File: state_changes.csv. Natural key: subject_type, subject_slug, field, occurred_at.
| Column | Required | Kind | Meaning |
|---|---|---|---|
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
field |
yes | text | What changed, named as the source named it. |
occurred_at |
yes | date | When it changed. Part of the key, because the same field changing twice is two events. |
from_value |
text | Empty means it had no value before. | |
to_value |
text | Empty means it was cleared. | |
note |
text |
verifications
Somebody checked that a finding was really resolved, or an action really done.
File: verifications.csv. Natural key: target_kind, subject_type, subject_slug, target_ref, target_variant, verified_at.
Leaving target_variant blank is a value rather than an absence: two rows that both leave it out name the same thing and the second is refused as a duplicate. Repeating another column’s value there is a different identity, not the same one written out.
target_variant carries no meaning when target_kind is action, and is not what tells two such rows apart.
| Column | Required | Kind | Meaning |
|---|---|---|---|
target_kind |
yes | text | What was checked. The schema allows only these two, because verifying a product means nothing: you verify a specific claim about it, and that claim is a finding or an action. One of: finding, action. |
subject_type |
yes | text | The subject the finding or action is about. One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
target_ref |
yes | text | The finding’s code, or the action’s title, on that subject. |
target_variant |
text | Which finding, where that subject carries the same code more than once. Leave blank rather than repeating target_ref: blank is its own identity, not a shorthand. Ignored when the target is an action. | |
verified_at |
yes | date | When it was checked. Part of the key, because the same thing is verified more than once and each check is its own record. |
result |
yes | text | One of: verified, not_verified, partial. |
verifier |
text | Who checked, by party display name. | |
note |
text | ||
evidence_uri |
text | The evidence the verification rests on, by uri from the evidence dataset. |
campaigns
A bounded audit: one lens, one obligation, one date range, one frozen population.
File: campaigns.csv. Natural key: slug.
| Column | Required | Kind | Meaning |
|---|---|---|---|
slug |
yes | text | Short identifier, used in links. |
name |
yes | text | |
status |
text | One of: draft, scoped, collecting, assessing, remediation, verification, closed, paused, cancelled. Defaults to draft. |
|
lens |
text | Which definition of ‘product’ the campaign counts under. | |
starts_on |
date | ||
ends_on |
date | ||
scope_frozen_at |
date | When the population stopped moving. The whole point of a campaign: a percentage means nothing if its denominator grew underneath it. | |
scope_query_json |
text | How the population was chosen, as JSON. | |
owner |
text | Who is accountable for the campaign, by party name. |
campaign_subjects
Which subjects a campaign counts, and which it deliberately does not.
File: campaign_subjects.csv. Natural key: campaign_slug, subject_type, subject_slug.
| Column | Required | Kind | Meaning |
|---|---|---|---|
campaign_slug |
yes | text | |
subject_type |
yes | text | One of: product, component, build_workflow, source_asset. |
subject_slug |
yes | text | |
included |
bool | False records a deliberate exclusion, which is not the same as absence: one is a decision, the other is an oversight. Defaults to True. |
|
exclusion_reason |
text | Required in practice when included is false, because an unexplained exclusion is indistinguishable from a mistake. | |
collection_status |
text | One of: not_started, collecting, ready, assessed, blocked. Defaults to not_started. |