Schema Developer FAQs
Some frequently asked questions about developing the NMDC Schema.
What are some effective strategies for collaborative schema development?
LinkML Collaborative Development Google Slides Presentation
How do I migrate from one version of the NMDC schema to another?
How do I view the NMDC schema programmatically?
NMDC SchemaView Documentation SchemaView Documentation
Where is the OWL generation documentation?
OWL Generation -- covers current build process, recommended config, CLI/YAML flag mapping, portal submission guidance, and upcoming LinkML changes.
Where should I put hand-written documentation?
The docs/ directory is a build output directory — make clean deletes
docs/*.md and docs/*.html. Tracked files in docs/ that have no
counterpart in src/docs/ will trigger a warning during make clean, but
untracked files will be silently removed. Place all hand-written documentation
in src/docs/ instead; the build copies it into docs/ automatically.
How do I configure environment variables for development scripts?
Some scripts need API keys or database credentials. Scripts that need them
load from local/.env via python-dotenv. To get started:
# IMPORTANT: Do NOT overwrite an existing local/.env — it may contain
# real credentials that are not recoverable from this repo.
if [ ! -f local/.env ]; then
cp .env.example local/.env
else
echo "local/.env already exists — not overwriting."
echo "Compare with .env.example to see if you need to add new variables:"
echo " diff <(sed 's/=.*//' .env.example) <(sed 's/=.*//' local/.env)"
fi
local/ is gitignored. .env.example in the repo root documents every
variable, which script uses it, and where to get credentials. You only need
to fill in the variables for the scripts you actually run.
The Docker-based migrator workflow has its own separate env file at
nmdc_schema/migrators/.docker/.env.example — see the
migrators README
for details.
What are LinkML readonly metaslots and why shouldn't I assert them?
The LinkML metamodel defines 12 readonly slots that are automatically populated
by the schema loader or generators: definition_uri, domain_of, from_schema,
generation_date, imported_from, is_usage_slot, metamodel_version, owner,
source_file, source_file_date, source_file_size, usage_slot_name.
Do not add these to hand-edited schema YAML files under src/schema/. The
loader fills them in at runtime, so asserting them is redundant and can cause
confusion when values drift from what the loader would compute.
For generated files like src/schema/mixs.yaml, the MIxS build pipeline
(makefiles/mixs.Makefile) strips all 12 readonly slots via yq eval as part
of the dematerialization step
(PR #2696).
What architectural changes were made between Oct 2025 and Feb 2026?
| Date | PR | Change |
|---|---|---|
| 2026-02-26 | #2848 | Makefile reorganization: MIxS pipeline moved to makefiles/mixs.Makefile, migrator targets to makefiles/migrators.Makefile. RDF conversion tooling removed. |
| 2026-02-26 | #2849 | LinkML 1.10.0 upgrade: new OWL flags (--enum-inherits-as-subclass-of), Python 3.9 dropped. |
| 2026-02-26 | #2846 | Dead code removal: about.yaml and experimental scripts removed. |
| 2026-02-21 | #2302 | Downloads page: schema-derived JSON and YAML files downloadable via docs website. |
| 2026-02-20 | #2839 | Unified LinkML CLI: build uses linkml generate owl, linkml generate json-schema, etc. instead of legacy gen-owl, gen-json-schema. |
| 2025-10-28 | #2696 | Dematerialize mixs.yaml: all 12 readonly metaslots stripped from generated mixs.yaml (35% line reduction). |