blob: 53f562c2f14b8d060ac2716cb37b271e26ec122f [file]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
---
openapi: 3.1.0
components:
schemas:
ConflictResponse:
type: object
properties:
qualifiedName:
type: string
recordStatus:
$ref: "#/components/schemas/RecordStatus"
entityType:
type: string
reason:
type: string
CustodyEventResponse:
type: object
properties:
agent:
type: string
action:
type: string
startTime:
type: string
recordStatus:
$ref: "#/components/schemas/RecordStatus"
lookupFailed:
type: boolean
DatasetErrorResponse:
type: object
properties:
error:
type: string
ErrorResponse:
type: object
properties:
message:
type: string
IngestResponse:
type: object
properties:
qualifiedName:
type: string
type:
type: string
recordStatus:
$ref: "#/components/schemas/RecordStatus"
validationIssues:
type: string
sha256:
type: string
validatedBy:
type: string
validatedAt:
type: string
Issue:
type: object
properties:
validatorId:
type: string
severity:
type: string
path:
type: string
message:
type: string
RecordResponse:
type: object
properties:
qualifiedName:
type: string
type:
type: string
recordStatus:
$ref: "#/components/schemas/RecordStatus"
name:
type: string
licenseId:
type: string
sourceUri:
type: string
modelUri:
type: string
modelVersion:
type: string
disclosure:
type: string
trainingData:
type: array
items:
$ref: "#/components/schemas/TrainingDataResponse"
custodyChain:
type: array
items:
$ref: "#/components/schemas/CustodyEventResponse"
validationIssues:
type: string
sha256:
type: string
validatedBy:
type: string
validatedAt:
type: string
RecordStatus:
type: string
enum:
- INCOMPLETE
- VALIDATED
SourcelumeDatasetDto:
type: object
required:
- qualifiedName
properties:
qualifiedName:
type: string
pattern: \S
name:
type: string
description:
type: string
guid:
type: string
recordStatus:
$ref: "#/components/schemas/RecordStatus"
rawJsonLd:
type: string
validationIssues:
type: string
sha256:
type: string
validatedBy:
type: string
validatedAt:
type: string
sourceUri:
type: string
licenseId:
type: string
typeName:
type: string
TrainingDataResponse:
type: object
properties:
dataset:
type: string
phase:
type: string
tokens:
type: integer
format: int64
share:
type: number
format: double
recordStatus:
$ref: "#/components/schemas/RecordStatus"
lookupFailed:
type: boolean
ValidationResponse:
type: object
properties:
conforms:
type: boolean
issues:
type: array
items:
$ref: "#/components/schemas/Issue"
ProvenanceRecord:
type: object
$schema: https://json-schema.org/draft/2020-12/schema
required:
- id
- type
- '@context'
- identifier
- name
- license
- creator
- created
- added
- contentCreated
- origin
- custodyChain
additionalProperties: true
description: "Minimal viable structural schema for a Sourcelume ProvenanceRecord:\
\ dataset identity, one or more role-tagged creators, one license claim, and\
\ an ordered custody chain. No signature block yet."
title: Apache Sourcelume Provenance Record (0.0.1)
properties:
'@context':
const: https://sourcelume.apache.org/context/0.0.1/sourcelume.jsonld
description: "Only the canonical context IRI is accepted. Inline @context\
\ objects and any other IRI are rejected, so a record's meaning is fixed\
\ by the published context."
id:
type: string
format: uri
type:
const: ProvenanceRecord
identifier:
type: string
minLength: 1
description: "Identifier for the dataset being described (e.g. a DOI or\
\ persistent URL), not for this record."
name:
type: string
minLength: 1
version:
type: string
license:
type: string
format: uri
description: IRI of the claimed license (e.g. an SPDX license page URL).
licenseScope:
type: string
minLength: 1
description: "Optional. Jurisdiction or scope in which the claimed `license`\
\ applies, for cases where a license (especially a public-domain claim)\
\ is jurisdiction-scoped rather than global. For example: 'US' for US\
\ judicial-work-product public domain, or 'jurisdictions with a life+70\
\ copyright term where the author died before 1954' for a copyright-expiration\
\ public-domain claim. Omit for licenses that apply globally (e.g. CC0,\
\ MIT)."
licenseNote:
type: string
minLength: 1
description: "Optional. Free-text qualifier for the claimed `license` IRI,\
\ for cases where the IRI alone is materially misleading. The classic\
\ case is a `license` IRI that reflects a processing artifact rather than\
\ an intended selection (e.g. a code subset that filters to a copyleft\
\ license by a bug, so the license IRI reads copyleft even though the\
\ intent was permissively-licensed code). Use this field to flag the discrepancy\
\ so an auditor does not take the bare IRI at face value. Omit when the\
\ IRI faithfully represents the licensing situation."
licenseCategory:
type: string
enum:
- open-source
- open-data
- public-domain
- agreement-supplied
- use-restricted
- risk-based
- other
description: "Optional. Category of the claimed `license`, so the license's\
\ licensing *model* is checkable at a glance rather than only by reading\
\ the IRI. The single `license` IRI cannot, by itself, distinguish a standard\
\ permissive open-source license (e.g. Apache 2.0, MIT) from a use-restricted\
\ license (open in IP grants but restricting specific harmful uses) from\
\ a risk-based license (tiered access by risk band). Categories: 'open-source'\
\ (standard permissive OSS, e.g. Apache 2.0), 'open-data' (standard permissive\
\ data license, e.g. ODC-By, CC0), 'public-domain' (CC Public Domain Mark\
\ or equivalent), 'agreement-supplied' (data shared under a bilateral\
\ agreement whose terms do not permit public sharing), 'use-restricted'\
\ (open IP grants but with use-based restrictions), 'risk-based' (tiered\
\ access by risk band), 'other'. Omit when the IRI is a well-known standard\
\ license whose category is obvious."
licenseHistory:
type: array
minItems: 1
items:
type: object
required:
- iri
- effectiveDate
additionalProperties: true
properties:
iri:
type: string
format: uri
effectiveDate:
type: string
format: date-time
description: "Optional. Record of prior licenses the dataset was distributed\
\ under, earliest first, when the dataset's own dataset-level license\
\ changed over time. The current license remains in the `license` field;\
\ this array records the superseded ones with their effective dates. Each\
\ entry is an object with `iri` (the prior license IRI) and `effectiveDate`\
\ (xsd:dateTime when that license became effective). Omit for datasets\
\ whose license has been stable since release. Example: a dataset released\
\ 2023-08 under a risk-based license, later switched to ODC-By, would\
\ carry `license` = ODC-By and `licenseHistory` = [{ iri: <prior-risk-based-license-IRI>,\
\ effectiveDate: 2023-08-01 }]."
creator:
type: array
minItems: 1
items:
type: object
required:
- type
- name
additionalProperties: true
properties:
type:
enum:
- schema:Organization
- schema:Person
name:
type: string
minLength: 1
role:
type: string
enum:
- originator
- curator
- distributor
description: "Optional. Distinguishes who created the underlying data\
\ from who curated or redistributed it. Omit if the record has a\
\ single, undifferentiated creator."
created:
type: string
format: date-time
added:
type: string
format: date-time
description: When this dataset was added to the collection being described
(e.g. when a source was incorporated into an aggregator corpus). Mirrors
the `added` field commonly found in dataset datasheets.
contentCreated:
type: string
format: date-time
description: "When the dataset's underlying documents/content were originally\
\ created (e.g. the historical date range of the texts). Mirrors the `created`\
\ field commonly found in dataset datasheets. If the content was created\
\ over a period, this is the start of the period and `contentCreatedEnd`\
\ is its end."
contentCreatedEnd:
type: string
format: date-time
description: "Optional. End of the period in which the dataset's underlying\
\ content was created, for content created over a period rather than at\
\ one point in time. `contentCreated` is the start of that period. Omit\
\ for content created at a single point in time. Must not be earlier than\
\ `contentCreated` (checked by the SHACL shapes)."
origin:
type: string
minLength: 1
description: Free-text description of where the dataset's underlying data
came from.
custodyChain:
type: array
minItems: 1
items:
type: object
required:
- agent
- action
- startTime
additionalProperties: true
properties:
agent:
type: string
format: uri
action:
type: string
minLength: 1
startTime:
type: string
format: date-time
description: "Ordered chain of custody events, earliest first. A single-hop\
\ dataset has exactly one entry."
$id: https://sourcelume.apache.org/schema/0.0.1/sourcelume.schema.json
TrainingProvenanceRecord:
type: object
$schema: https://json-schema.org/draft/2020-12/schema
required:
- id
- type
- '@context'
- identifier
- name
- creator
- created
- disclosure
if:
properties:
disclosure:
enum:
- complete
- partial
then:
required:
- trainingData
additionalProperties: true
description: "Structural schema for a Sourcelume TrainingProvenanceRecord: a\
\ model producer's claim of which datasets a model was trained on. Datasets\
\ are referenced by IRI (typically the `id` of a ProvenanceRecord); their\
\ provenance is not repeated here. No signature block yet."
title: Apache Sourcelume Training Provenance Record (0.0.1)
properties:
'@context':
const: https://sourcelume.apache.org/context/0.0.1/sourcelume.jsonld
description: "Only the canonical context IRI is accepted. Inline @context\
\ objects and any other IRI are rejected, so a record's meaning is fixed\
\ by the published context."
id:
type: string
format: uri
type:
const: TrainingProvenanceRecord
identifier:
type: string
minLength: 1
description: "Identifier for the model being described (e.g. a DOI or persistent\
\ URL), not for this record."
name:
type: string
minLength: 1
description: Human-readable model name.
version:
type: string
description: "Model version or checkpoint, if versioned."
creator:
type: array
minItems: 1
items:
type: object
required:
- type
- name
additionalProperties: true
properties:
type:
enum:
- schema:Organization
- schema:Person
name:
type: string
minLength: 1
role:
type: string
enum:
- originator
- curator
- distributor
description: "Optional. Same meaning as in ProvenanceRecord, applied\
\ to the model."
description: The party or parties that produced the model and make this
claim.
created:
type: string
format: date-time
description: "When this training provenance record was authored (record\
\ metadata, not a training date)."
disclosure:
type: string
enum:
- complete
- partial
- undisclosed
description: "How much of the training data the producer discloses in `trainingData`.\
\ 'complete': every training dataset is listed. 'partial': only some are\
\ listed. 'undisclosed': the producer does not disclose its training data;\
\ `trainingData` may then be omitted. This is the producer's own statement\
\ about its disclosure, not a judgement by Sourcelume."
trainingData:
type: array
minItems: 1
items:
type: object
required:
- dataset
additionalProperties: true
properties:
dataset:
type: string
format: uri
description: "IRI of the dataset. Normally the `id` of a Sourcelume\
\ ProvenanceRecord, so its provenance can be resolved. May also\
\ be any other dataset IRI (for example a repository page) when\
\ no record exists."
phase:
type: string
enum:
- pretraining
- fine-tuning
- alignment
- evaluation
description: "Optional. Training phase in which the dataset was used.\
\ Omit when the producer does not distinguish phases. 'fine-tuning'\
\ covers instruction, SFT and retrieval-grounding stages; 'evaluation'\
\ is for held-out sets the model was tested on, not trained on."
tokens:
type: integer
description: "Optional. Number of tokens drawn from the dataset (per\
\ epoch, or in total; say which in `note`)."
minimum: 0
share:
type: number
description: "Optional. Fraction of the phase's training tokens that\
\ came from this dataset, between 0 and 1."
maximum: 1
minimum: 0
description: "The datasets the model was trained on, in no particular order.\
\ Required unless `disclosure` is 'undisclosed'."
note:
type: string
minLength: 1
description: "Optional. Free-text qualifier for the claim, e.g. where the\
\ full list is published, or whether `tokens` are per epoch or in total."
$id: https://sourcelume.apache.org/schema/0.0.1/sourcelume-training.schema.json
IncompleteRecordSubmission:
type: object
required:
- id
description: A non-conforming record retained for curation. Only a nonblank
id is needed for storage; missing or unknown record types are reported through
validation issues.
properties:
id:
type: string
pattern: \S
RecordSubmission:
description: A dataset or model provenance record. The spec schemas describe
conforming records; incomplete records with a nonblank id may also be submitted
for curation.
anyOf:
- $ref: "#/components/schemas/ProvenanceRecord"
- $ref: "#/components/schemas/TrainingProvenanceRecord"
- $ref: "#/components/schemas/IncompleteRecordSubmission"
RecordValidationRequest:
description: Any JSON document to check against the ProvenanceRecord or TrainingProvenanceRecord
schema. No record fields are required before validation; non-conforming documents
return 422 with validation issues.
examples:
DatasetRecord:
summary: Dataset provenance
value:
'@context': https://sourcelume.apache.org/context/0.0.1/sourcelume.jsonld
id: https://example.org/records/dataset-v1
type: ProvenanceRecord
identifier: https://example.org/datasets/example-v1
name: Example dataset
license: https://www.apache.org/licenses/LICENSE-2.0
creator:
- type: schema:Organization
name: Example Organization
created: 2026-10-01T00:00:00Z
added: 2026-10-01T00:00:00Z
contentCreated: 2026-10-01T00:00:00Z
origin: An example dataset published by its producer.
custodyChain:
- agent: https://example.org/
action: created
startTime: 2026-10-01T00:00:00Z
TrainingRecord:
summary: Model training provenance
value:
'@context': https://sourcelume.apache.org/context/0.0.1/sourcelume.jsonld
id: https://example.org/records/model-v1
type: TrainingProvenanceRecord
identifier: https://example.org/models/example-v1
name: Example model
creator:
- type: schema:Organization
name: Example Organization
created: 2026-10-01T00:00:00Z
disclosure: complete
trainingData:
- dataset: https://example.org/records/dataset-v1
phase: pretraining
tokens: 1000
share: 1.0
IncompleteRecord:
summary: "Incomplete record: returns validation issues"
value:
id: https://example.org/records/incomplete
MissingRecordId:
summary: "Missing id: pre-flight returns 422; cannot be stored"
value:
type: ProvenanceRecord
tags:
- name: Datasets
description: Read-only views of dataset entities; provenance records are written
via /records
- name: Records
description: Submit provenance records and read their verdicts
- name: Types
description: The Sourcelume type definitions registered in the backend
paths:
/api/v1/datasets:
get:
summary: Get a dataset by qualifiedName
tags:
- Datasets
parameters:
- description: The dataset's qualified name
required: true
name: qualifiedName
in: query
schema:
type: string
responses:
"200":
description: The dataset
content:
application/json:
schema:
$ref: "#/components/schemas/SourcelumeDatasetDto"
"400":
description: Missing qualifiedName
content:
application/json:
schema:
$ref: "#/components/schemas/DatasetErrorResponse"
"404":
description: No dataset for this qualifiedName
content:
application/json:
schema:
$ref: "#/components/schemas/DatasetErrorResponse"
/api/v1/datasets/guid/{guid}:
get:
summary: Get a dataset by its backend GUID
tags:
- Datasets
parameters:
- name: guid
in: path
required: true
schema:
type: string
responses:
"200":
description: The dataset
content:
application/json:
schema:
$ref: "#/components/schemas/SourcelumeDatasetDto"
"404":
description: No dataset for this GUID
content:
application/json:
schema:
$ref: "#/components/schemas/DatasetErrorResponse"
/api/v1/datasets/{qualifiedName}:
get:
summary: Get a dataset by qualifiedName in the path
tags:
- Datasets
parameters:
- name: qualifiedName
in: path
required: true
schema:
type: string
pattern: .+
responses:
"200":
description: The dataset
content:
application/json:
schema:
$ref: "#/components/schemas/SourcelumeDatasetDto"
"404":
description: No dataset for this qualifiedName
content:
application/json:
schema:
$ref: "#/components/schemas/DatasetErrorResponse"
/api/v1/types/dataset:
get:
summary: Get the dataset entity definition
tags:
- Types
responses:
"200":
description: "The sourcelume_dataset entity definition and the enums its\
\ attributes use, in the typedefs format"
content:
application/json:
schema:
type: object
/api/v1/types/model:
get:
summary: Get the model entity definition
tags:
- Types
responses:
"200":
description: "The sourcelume_model entity definition and the enums its attributes\
\ use, in the typedefs format"
content:
application/json:
schema:
type: object
/api/v1/types/typedefs:
get:
summary: Get the Sourcelume typedefs
tags:
- Types
responses:
"200":
description: The typedefs model
content:
application/json:
schema:
type: object
/records:
post:
summary: Submit a provenance record
description: "Validates the record synchronously and stores it byte-identical\
\ with its verdict: VALIDATED (published, no longer changeable) or INCOMPLETE\
\ (carries its issues, corrected by resubmitting)."
tags:
- Records
requestBody:
description: A dataset or model provenance record as JSON-LD. Records with
a nonblank id that fail spec validation are also accepted and stored as
INCOMPLETE with their validation issues.
content:
application/ld+json:
examples:
dataset:
$ref: "#/components/examples/DatasetRecord"
model:
$ref: "#/components/examples/TrainingRecord"
incomplete:
$ref: "#/components/examples/IncompleteRecord"
schema:
$ref: "#/components/schemas/RecordSubmission"
application/json:
examples:
dataset:
$ref: "#/components/examples/DatasetRecord"
model:
$ref: "#/components/examples/TrainingRecord"
incomplete:
$ref: "#/components/examples/IncompleteRecord"
schema:
$ref: "#/components/schemas/RecordSubmission"
required: true
responses:
"201":
description: New record stored with its verdict
headers:
Location:
description: The record's status view
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/IngestResponse"
"200":
description: Existing record resubmitted and stored with its new verdict
headers:
Location:
description: The record's status view
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/IngestResponse"
"400":
description: Unparseable document or no usable id
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"409":
description: "The record is already VALIDATED, or the id is taken under\
\ a different record type"
content:
application/json:
schema:
$ref: "#/components/schemas/ConflictResponse"
"415":
description: Unsupported content type
/records/validate:
post:
summary: Validate a provenance record without storing it
description: "Runs the validator chain (JSON Schema, then SHACL), stopping at\
\ the first failing stage."
tags:
- Records
requestBody:
description: "A dataset or model provenance record as JSON-LD. Non-conforming\
\ records, including records without an id, return 422 with validation issues."
content:
application/json:
examples:
dataset:
$ref: "#/components/examples/DatasetRecord"
model:
$ref: "#/components/examples/TrainingRecord"
incomplete:
$ref: "#/components/examples/IncompleteRecord"
missingId:
$ref: "#/components/examples/MissingRecordId"
schema:
$ref: "#/components/schemas/RecordValidationRequest"
required: true
responses:
"200":
description: The record conforms
content:
application/json:
schema:
$ref: "#/components/schemas/ValidationResponse"
"422":
description: "The record does not conform, or is not valid JSON"
content:
application/json:
schema:
$ref: "#/components/schemas/ValidationResponse"
/records/{id}:
get:
summary: Get a record's stored state and verdict
description: "For a VALIDATED TrainingProvenanceRecord, each trainingData entry\
\ also reports the current status of the referenced dataset record; for a\
\ VALIDATED ProvenanceRecord, each custodyChain event reports the current\
\ status of the record its agent names, if any. Both are looked up at read\
\ time."
tags:
- Records
parameters:
- description: The record's id (IRI); encode it when calling the API directly
name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: The stored record
content:
application/json:
schema:
$ref: "#/components/schemas/RecordResponse"
"404":
description: No record for this id
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
info:
title: Apache Sourcelume Registry API
version: 0.0.1-SNAPSHOT
description: "Submit, validate and query Apache Sourcelume provenance records."
license:
name: Apache License 2.0
url: https://www.apache.org/licenses/LICENSE-2.0