RAID-831: DataCite 4.7 LinkML schema + RAiD→DataCite crosswalk (spike) - #620
Merged
Conversation
Spike deliverable: a hand-authored LinkML rendering of the DataCite 4.7 metadata schema (the importer schemauto import-xsd does not handle this XSD), and a field-by-field RAiD->DataCite crosswalk authored from the current Java factories, with a declarable-vs-imperative feasibility verdict. The LinkML schema is an inert spike artifact (not wired into the datamodel gradle build). Validated with gen-json-schema via linkml/linkml:1.9.2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…bset Configures the declarable part of the RAiD->DataCite crosswalk as a linkml-map TransformationSpecification (constant types, titles/descriptions with vocab enum_derivations, dates concatenation) and transforms a sample RaidDto into a DataCite 4.7-shaped instance against the real raid-core.yaml (verified, exit 0). Confirms the imperative floor (live PID name resolution, org split) cannot be expressed. Cross-referenced from the crosswalk doc. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… not achievable in-app) Adds an execution-model section to the crosswalk: linkml-map is Python with no JVM runtime, so the transform can inform Java code but cannot drive it; the factories stay (mapping stays in code); porting linkml-map is a large, ongoing build dominated by re-creating ~20k LOC of linkml_runtime plus expr-semantics parity, and still cannot cross the imperative floor. Realistic win = a governed, single-sourced vocabulary crosswalk consumed by the existing factories. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The crosswalk note answered questions 1-3 and part of 5. Adds the rest, plus a new assessment the earlier execution-model section did not cover. - Hand-rolled build-time generator: feasible, and the three objections to porting linkml-map do not apply (own dialect, no expression language, no upstream to track). Precedent is already in buildSrc (AddStaticEnums, GenerateReferenceDataTask, Utils) and openApiGenerate; needs no Docker, so it can run in CodeBuild. Buys a build-time exhaustiveness check that fixes the silent-null unmapped-vocab issue. Recommend the governed vocab table first, generation as its destination. - Q5: resolution as an enrichment step before the crosswalk, and Appendix 3 unknown values (:unav) at that boundary; richness gaps listed. - Q4: version per (RAiD, DataCite) pair; re-sync via RAID-832's flag + worker. - Q6: same toolset, different mechanism; narrows RAID-776's "mappings as config" claim to schema.org only. - Q7: RAID-797 as the worked example - two production lines; the cost was noticing and re-pushing, not the edit. - Testing NFR: four layers, incl. the gated DATACITE_LIVE_TEST pattern. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Link the two surfaced bugs to their tickets: RAID-858 (publicationYear hardcoded to Year.now()) and RAID-859 (rightsList never emitted). Both re-verified against post-merge code and still present on main. - RAID-797 has merged, so relatedRaid now emits the native "RAiD" relatedIdentifierType, not "DOI". Update the field-mapping row and mark Known issue 3 resolved, retained for provenance. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Abdul-ardc
approved these changes
Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
RAID-831 is a spike: investigate a LinkML-driven RAiD→DataCite metadata crosswalk. This PR delivers the spike's two artifacts and a feasibility verdict. It does not change any runtime behaviour.
Ticket: RAID-831. Related: RAID-796 (DataCite schema alignment epic), RAID-832 (re-sync mechanism, which defers the crosswalk here), RAID-377 (mapping update to DataCite 4.7), RAID-776 (origin spike that proposed this).
Deliverables
api-svc/datamodel/src/v2/datacite.yaml— a hand-authored LinkML rendering of the DataCite 4.7 metadata schema (24 classes, 10 controlled-vocabulary enums with values taken verbatim from the XSD). It is an inert spike artifact: not referenced by the datamodel gradle build, so it does not affect codegen or CI. Validates withgen-json-schemavialinkml/linkml:1.9.2(exit 0, no warnings).doc/reference/raid-datacite-crosswalk.md— a field-by-field RAiD→DataCite crosswalk authored from the current Java factories underapi-svc/raid-api/.../factory/datacite/, including the controlled-vocabulary lookup tables and a declarable-vs-imperative verdict.Feasibility verdict (the spike's answer)
schemauto import-xsd(linkml/schema-automator, the only maintained importer) fails on DataCite'sxs:allroot, and after that workaround fails again in itssimpleContent/extension handling. The schema was therefore hand-authored from the XSD.exact_mappings+linkml-map, with the code→enum maps expressible as SSSOM tables. But two things form an imperative floor that cannot be declarative: every person/org name is resolved live from ORCID/ISNI/ROR at emission time, and the single RAiDorganisation[]list is split into contributors vs. fundingReferences (with a "latest role" reduce) by predicate logic. Recommendation: declarative vocab tables feeding a thin imperative adapter.Targeted at DataCite 4.7
Built against 4.7 (not 4.6) to match RAID-377. The 4.6→4.7 delta captured here:
relatedIdentifierTypeaddsRAiDandSWHID;resourceTypeGeneraladdsPoster/Presentation;relationTypeaddsOther; and a new optionalrelationTypeInformationon relatedIdentifier/relatedItem. Notably, 4.7 addingRAiDnatively is what makes RAID-797's native-RAiDemission schema-valid (RAID-797 emitted it ahead of the published XSD, relying on the REST API accepting it early).Bugs surfaced (not fixed here — flagged for their own tickets)
publicationYearis hardcoded toYear.now()in all threeDataciteAttributesDtoFactoryoverloads (there is a// TODO), so an update in a later year silently rewrites the DOI's publication year.rightsListis never emitted —DataciteRightFactoryis injected but never called, so RAiD's licence never reaches DataCite.🤖 Generated with Claude Code