Notable changes to dds.yaml (the Data Definition Specification LinkML schema). Format loosely
follows Keep a Changelog. The schema is not yet
semver-versioned, so entries are dated.
Repositions the schema as a standards-agnostic canonical model: ODM/Define-XML
is one serialization facet applied by the output generator, not the source of the
model. Applied as a series of atomic commits; each change validated with
gen-linkml. Breaking (class/slot renames). Generated docs need a make docs
refresh and downstream instances must migrate renamed names.
- Moved the required-
OIDslot_usagefrom theGovernedmixin (which does not inheritIdentifiable, whereOIDis defined) toGovernedElement(§1.2). - Demoted OMOP era mappings on
Timingfromnarrow_mappings(false OWL subsumption) torelated_mappings; kept FHIR Period/Age/Duration as narrow (§1.3). - Removed invalid
from_schema: ncit:C…fromOriginType/OriginSource(it must be a schema URI); provenance preserved in descriptions (§1.4).
- Neutral schema
id(https://w3id.org/dds) anddefault_prefix: dds(addedddsprefix) replacing thecdisc.org/odmdefaults; description reframed as standards-agnostic. (Neutral namespace chosen over the doc'scdisc.org.)
ReifiedConcept→Concept;MetaDataVersion→Specification(tree_root);WhereClause→ApplicabilityCondition(+whereClausesslot →applicabilityConditions);Condition→LogicalPredicate(+conditionsslots →predicates/validationPredicates,collectionExceptionCondition→collectionExceptionPredicate,implementsCondition→implementsPredicate; externalusdm:Condition/odm:ConditionDefmappings preserved);ODMFileMetadata→ODMSerializationMetadata;IsODMItem→ODMItemSerialization;IsODMStandard→ODMStandardReference.
- Detached
ODMSerializationMetadatafromSpecificationandODMItemSerializationfromItem(generator-applied, not canonical) (§3.1/§3.2). - Replaced
NominalOccurrence(planned/actual conflation) with aTimingLandmarkenum + free-form USDMScheduledActivityInstancereference onTiming.relativeTo/relativeFrom(§3.3). - Added
Specification.usdmStudyDesignId(defer study design to USDM) (§3.4). - Flipped
Dataflow.analysisMethod→Analysis.inputDataflows(correct dependency direction) (§3.5). - Annotated
ItemGroupType.ValueListas an ODM serialization hint (§3.6).
Backward-compatible / additive. New classes/slots/enum only; one slot
repurposed (keySequence) with a new sibling added. No existing instances populate
the affected slots. Verified: gen-linkml and linkml-lint pass.
- Class
Query(is_a GovernedElement,close_mappings: odm:Query): a reified, externally referenced query linked many-to-many to metadata and/or data elements viaabout(non-inlined OID references), withqueryType,text,status,source. Catalogued in the newMetaDataVersion.queriescollection (#2). - Class
Check(is_a GovernedElement): a reusable validation check (e.g. a published CORE rule) linked many-to-many viaappliesTo(non-inlined), withpublishedBy,externalReference(uri/curie),severity, and optionalexpressions. Catalogued in the newMetaDataVersion.checkscollection.RangeCheck.implementsCheckreferences aCheckto connect inline checks to the reusable rule they implement (#1). - Enum
QueryType(Internal/External) forQuery.queryType(#2). ItemGroup.uniqueKey: unordered set of Items establishing record uniqueness (carries theodm:ItemRef.KeySequencemapping) (#12).
ItemGroup.keySequencerepurposed to mean sort order only (ordered, may include non-key Items); uniqueness moved to the newuniqueKey. Resolves the prior overloading of one slot for sorting + uniqueness + merge (#12).
Backward-compatible / additive only. No classes or slots were removed, no new
required fields were added to existing classes, and no inlining was changed on any
slot used by existing instances. Verified: the full define files still load and
validate, and examples/concept_method_example.json (the only file using the
concept slots) is unaffected. Net change +209 lines (2562 → 2771).
Representing a Data Transfer Agreement (DTA) exposed three structural gaps:
- A DTA could not be serialised as a self-contained artifact.
ProvisionAgreementexisted, but itsprovider/dataFlow/sourcewere non-inlined references with no container reachable from the tree root — so the agreement couldn't hold its own parts. - No agreement-level delivery timing. Timing existed only on concrete
Datasetreporting periods, not as a transfer schedule on the flow/agreement. - No structured home for legal/governance terms.
hasPolicywas untyped, there was noDataConsumer(asymmetric withDataProvider), and confidentiality/permitted-use/ retention terms were unmodelled.
Design decisions taken (with the user, as a peer): the DTA is a standalone artifact that embeds a frozen snapshot of the agreed structure and links to the live spec for provenance; the canonical concept layer is referenced (Registry), not embedded; legal terms use ODRL; the schedule default is a domain-neutral ISO-8601 string so the model stays clinical-first but horizontal-ready.
- Prefix
odrl(http://www.w3.org/ns/odrl/2/). Reason: legal terms are modelled with ODRL; the schema already used DPROD/DCAT, which express policy via ODRL. ProvisionAgreement.hasPolicy→Policy(multivalued, inlined). Reason: the agreement is the legal instrument but previously had nowhere to carry its terms (gap 3).Dataflow.deliverySchedule→any_of [string, Timing](multivalued, inlined). Reason: agreement-level transfer cadence (gap 2). Default is an ISO-8601 repeating interval string (neutral);Timingremains available for clinical anchoring. Concrete reporting periods stay onDatasetviaIsSdmxDataset.*.DataProduct.provisionAgreement→ProvisionAgreement(multivalued, not inlined). Reason: lets a data product catalogue the DTAs governing its flows by OID/URI, while the DTA stays an independently maintained artifact.- Class
DataConsumer(is_a Organization,close_mappings: sdmx:DataConsumer). Reason: restores symmetry withDataProvider; gives the demand side a typed home (consumesDataFrom,provisionAgreements) (gap 3). - Class
Policy(exact_mappings: odrl:Policy,close_mappings: dcat:hasPolicy) withpolicyType,profile,assigner,assignee, andpermission/prohibition/obligationrule lists. Reason: structured legal terms for the DTA (gap 3). - Class
Rule(odrl:Rule) withaction,target,assigner/assignee,constraint. Reason: ODRL permission/prohibition/duty semantics. - Class
Constraint(odrl:Constraint) withleftOperand/operator/rightOperand/unit. Reason: expresses conditions such aspurpose eq "safety-reporting". - Enum
PolicyType(Set/Offer/Agreement, mapped to ODRL). Reason: typedPolicy.policyType; a DTA is an ODRLAgreement. - Enum
ConstraintOperator(eq/neq/lt/lteq/gt/gteq/isPartOf/isA/isAnyOf/isNoneOf, mapped to ODRL). Reason: typedConstraint.operator.
ProvisionAgreement.provider,.dataFlow,.source→inlined: trueandDataflow.structure→inlined: true. Reason: a standalone DTA must be a self-contained, signable snapshot (gap 1). These slots are not used by existing instances, so the change is non-breaking.ProvisionAgreement.consumerany_ofnow includesDataConsumer(ahead ofDataProduct/Organization/string). Reason: allow the typed consumer; existing string/Organization values remain valid.Dataset.hasPolicyandDataProduct.hasPolicy→range: Policy. Reason: both were untyped (no range); typing them makes governance terms machine-checkable. No existing file populated these slots, so no migration is needed.
- Declared the
ncitprefix (http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl#). Reason:ncit:*CURIEs were used in enummeanings but the prefix was undeclared (#14). Parameter.required.ifabsentandDataStructureDefinition.evolvingStructure.ifabsentchanged from the bare booleanfalseto the string'False'. Reason: the metamodel typesifabsentas string/null, so an unquoted boolean failed validation (#23).Analysis.analysisMethod: movedany_ofout of thedescriptiontext (it was indented under it, so it was inert) and setrange: Method; the previously referencedAnalysisMethodclass does not exist (#17).- Standardised string-type declarations: added schema-level
default_range: stringand removed the 52 redundant explicitrange: stringslot facets.any_ofmembers (- range: string) are retained as they are explicit union alternatives. Semantically identical to the prior state, so no instances are affected (#13).
- The schema has no
versionfield; consider adding one to make changes citable. - Generated docs under
docs/are produced from the schema and need agen-docrefresh to include the new classes. - A pinned copy of this schema lives in the
data-definition-dtaskill bundle (reference/define.yaml) and should be re-synced when the canonical schema changes.