10 KiB
Slot Naming Conventions for Hyper-Modular Schema
Version: 0.1.0
Date: 2025-11-21
Schema: Heritage Custodian Observation and Reconstruction Pattern
Overview
In a hyper-modular schema where each slot is defined in its own file, we need clear conventions for handling semantically identical slots with different ranges (typing constraints).
Problem: The same ontological property (e.g., prov:wasRevisionOf) may need to be applied to multiple classes with different range constraints:
was_revision_offorCustodianReconstruction→ previousCustodianReconstructionwas_revision_offorRecord→ previousRecordwas_revision_offorCollection→ previousCollection
Solution: Co-locate range-specialized variants in the same file, using hyphenated suffixes to distinguish slot names.
Naming Convention
Rule 1: Base Slot Name = Primary/First Use Case
The first defined slot uses the base name without suffix:
# File: modules/slots/was_revision_of.yaml
slots:
was_revision_of:
slot_uri: prov:wasRevisionOf
range: CustodianReconstruction # Primary use case
description: "Previous version of this reconstruction (if updated)"
File location: /modules/slots/was_revision_of.yaml
Slot name: was_revision_of (no suffix)
Rule 2: Range-Specialized Variants = Hyphenated Suffix
Subsequent slots with different ranges but the same slot_uri are added to the same file with hyphenated suffixes:
# File: modules/slots/was_revision_of.yaml (SAME FILE)
slots:
was_revision_of:
slot_uri: prov:wasRevisionOf
range: CustodianReconstruction
description: "Previous version of this reconstruction (if updated)"
was_revision_of-record:
slot_uri: prov:wasRevisionOf # SAME ontological property
range: Record # DIFFERENT range
description: "Previous version of this record (if updated)"
was_revision_of-collection:
slot_uri: prov:wasRevisionOf
range: Collection
description: "Previous version of this collection (if updated)"
Hyphen placement: {base_slot_name}-{range_type_lowercase}
Examples:
was_revision_of→CustodianReconstruction(base)was_revision_of-record→Record(specialized)was_revision_of-collection→Collection(specialized)was_revision_of-observation→CustodianObservation(specialized)
Rule 3: File Organization
Single file per ontological property, containing all range variants:
modules/slots/
├── was_revision_of.yaml # Contains: was_revision_of, was_revision_of-record, was_revision_of-collection
├── was_derived_from.yaml # Contains: was_derived_from, was_derived_from-entity
├── identifier_scheme.yaml # Contains: identifier_scheme (single variant - no specialization needed)
└── ...
Benefits:
- ✅ Easy to find all variants of a property (one file)
- ✅ Centralized documentation of ontological alignment
- ✅ Clear relationship between semantically identical slots
- ✅ Reduces file count (59 files vs. potentially 100+ with separate files per variant)
Why Hyphens?
✅ Hyphens ARE allowed in LinkML slot names
LinkML permits hyphens (-) in slot identifiers:
from linkml_runtime.linkml_model import SlotDefinition
# All valid:
SlotDefinition(name="was_revision_of") # Underscores
SlotDefinition(name="was-revision-of") # Hyphens
SlotDefinition(name="was_revision_of-record") # Mixed
Advantages of Hyphen Suffix Convention
-
Visual Separation:
was_revision_of-recordclearly shows:was_revision_of= base semantic concept-record= range specialization suffix
-
Avoids Double Underscores: Using underscores would create:
- ❌
was_revision_of_record(ambiguous: is it "was_revision" of "of_record"?) - ✅
was_revision_of-record(clear: "was_revision_of" specialized for "record")
- ❌
-
Consistency with LinkML Module Names: LinkML uses hyphens in module IDs:
was-revision-of-slot(module name)was_revision_of-record(slot name)
Exceptions and Edge Cases
Exception 1: Single-Range Slots
If a slot is only used with one range, no suffix is needed:
# File: modules/slots/legal_name.yaml
slots:
legal_name:
slot_uri: cpov:legalName
range: string # Single, unchanging range
description: "Official legal name as registered"
No variants: legal_name-string is NOT needed (strings are the universal default).
Exception 2: Slots with Multiple Acceptable Ranges (Union Types)
If a slot accepts multiple ranges simultaneously (union type), use any_of:
# File: modules/slots/subject.yaml
slots:
subject:
slot_uri: dcterms:subject
any_of:
- range: string
- range: Concept
- range: uriorcurie
description: "Subject or topic (string, SKOS Concept, or URI)"
No hyphenated variants needed: This is a single polymorphic slot, not multiple specialized slots.
Exception 3: Ontologically Distinct Properties
If two slots have different slot_uri values, they belong in separate files:
# File: modules/slots/was_revision_of.yaml
slots:
was_revision_of:
slot_uri: prov:wasRevisionOf # PROV-O revision
# File: modules/slots/replaces.yaml (SEPARATE FILE)
slots:
replaces:
slot_uri: dcterms:replaces # DIFFERENT ontological property
Even if both represent "replaces previous version" semantically, different ontology properties = different files.
Implementation Guidelines
When Adding a New Range Variant
- Check if slot file exists: Look for
modules/slots/{base_slot_name}.yaml - Check ontological alignment: Does the new slot use the same
slot_uri? - If YES: Add to existing file with hyphenated suffix
- If NO: Create new file with appropriate base name
Example: Adding was_revision_of-observation
# 1. Check existing file
cat modules/slots/was_revision_of.yaml
# 2. Verify slot_uri matches (prov:wasRevisionOf)
# 3. Add new variant to SAME file
# File: modules/slots/was_revision_of.yaml
id: https://nde.nl/ontology/hc/slot/was_revision_of
name: was-revision-of-slot
imports:
- ../classes/CustodianReconstruction
- ../classes/CustodianObservation # NEW import
slots:
was_revision_of:
slot_uri: prov:wasRevisionOf
range: CustodianReconstruction
description: "Previous version of this reconstruction (if updated)"
was_revision_of-observation: # NEW variant
slot_uri: prov:wasRevisionOf
range: CustodianObservation
description: "Previous version of this observation (if updated)"
Update aggregator (modules/slots_all.yaml):
imports:
- slots/was_revision_of # Already imports file (contains both variants now)
No change needed: Aggregator imports the file, which now contains both slots.
Documentation Requirements
Each slot file containing multiple variants MUST include:
- File-level comment explaining the ontological property
- Import statements for ALL range classes
- Slot-level descriptions distinguishing each variant
Example:
# CustodianReconstruction Slot: was_revision_of
# PROV-O wasRevisionOf property with multiple range specializations
id: https://nde.nl/ontology/hc/slot/was_revision_of
name: was-revision-of-slot
imports:
- ../classes/CustodianReconstruction
- ../classes/CustodianObservation
- ../classes/Record
- ../classes/Collection
slots:
was_revision_of:
slot_uri: prov:wasRevisionOf
range: CustodianReconstruction
description: >-
Previous version of this reconstruction (if updated).
PROV-O: wasRevisionOf for CustodianReconstruction versioning.
was_revision_of-observation:
slot_uri: prov:wasRevisionOf
range: CustodianObservation
description: >-
Previous version of this observation (if updated).
PROV-O: wasRevisionOf for CustodianObservation versioning.
was_revision_of-record:
slot_uri: prov:wasRevisionOf
range: Record
description: >-
Previous version of this record (if updated).
PROV-O: wasRevisionOf for Record versioning.
comments:
- "All variants map to PROV-O prov:wasRevisionOf"
- "Range specialization enables type-safe versioning"
- "Hyphenated suffix pattern: {base_name}-{range_lowercase}"
Rationale: Why Co-location?
Alternative 1: Separate Files Per Variant ❌
modules/slots/
├── was_revision_of.yaml
├── was_revision_of_record.yaml
├── was_revision_of_collection.yaml
├── was_revision_of_observation.yaml
Problems:
- ❌ File explosion (59 slots → 150+ files with variants)
- ❌ Difficult to see all variants of a property
- ❌ Duplicated ontology documentation across files
- ❌ Import bloat in aggregator
Alternative 2: Co-location with Hyphenated Suffixes ✅
modules/slots/
├── was_revision_of.yaml # Contains all 4 variants
Benefits:
- ✅ Manageable file count
- ✅ Single source of truth for ontological property
- ✅ Easy maintenance (one file to update)
- ✅ Clear relationship between variants
Summary
| Convention | Rule | Example |
|---|---|---|
| Base slot | No suffix | was_revision_of |
| Range variant | Hyphenated suffix | was_revision_of-record |
| File location | Single file per ontological property | /slots/was_revision_of.yaml |
| File contains | All range variants | was_revision_of, was_revision_of-record, ... |
| Suffix format | -{range_lowercase} |
-record, -observation, -collection |
| When to create variant | Same slot_uri, different range |
slot_uri: prov:wasRevisionOf |
| When to create new file | Different slot_uri |
prov:wasRevisionOf vs dcterms:replaces |
References
- LinkML Slot Definition: https://linkml.io/linkml/schemas/slots.html
- PROV-O wasRevisionOf: https://www.w3.org/TR/prov-o/#wasRevisionOf
- Heritage Custodian Schema:
/schemas/20251121/linkml/01_custodian_name_modular.yaml
Last Updated: 2025-11-21
Maintainer: GLAM Data Extraction Project