glam/.opencode/rules/no-ontology-prefix-in-slot-names.md

5.8 KiB

Rule 42: No Ontology Prefixes in Slot Names

CRITICAL: LinkML slot names MUST NOT include ontology namespace prefixes. Ontology references belong in mapping properties, NOT in element names.


1. The Problem

Slot names like rico_has_or_had_holder or skos_broader violate separation of concerns:

  • Slot names should describe the semantic meaning in plain, readable terms
  • Ontology mappings belong in slot_uri, exact_mappings, close_mappings, related_mappings, narrow_mappings, broad_mappings

Embedding ontology prefixes in names:

  1. Creates coupling between naming and specific ontology versions
  2. Reduces readability for non-ontology experts
  3. Duplicates information already in mapping properties
  4. Makes future ontology migrations harder

2. Correct Pattern

Use Descriptive Names + Mapping Properties

# CORRECT: Clean name with ontology reference in slot_uri
slots:
  record_holder:
    description: The custodian that holds or held this record set.
    slot_uri: rico:hasOrHadHolder
    exact_mappings:
      - rico:hasOrHadHolder
    close_mappings:
      - schema:holdingArchive
    range: Custodian

WRONG: Ontology Prefix in Name

# WRONG: Ontology prefix embedded in slot name
slots:
  rico_has_or_had_holder:  # BAD - "rico_" prefix
    description: The custodian that holds or held this record set.
    slot_uri: rico:hasOrHadHolder
    range: string

3. Prohibited Prefixes in Slot Names

The following prefixes MUST NOT appear at the start of slot names:

Prefix Ontology Example Violation
rico_ Records in Contexts rico_organizational_principle
skos_ SKOS skos_broader, skos_narrower
schema_ Schema.org schema_name
dcterms_ Dublin Core dcterms_created
dct_ Dublin Core dct_identifier
prov_ PROV-O prov_generated_by
org_ W3C Organization org_has_member
crm_ CIDOC-CRM crm_carried_out_by
foaf_ FOAF foaf_knows
owl_ OWL owl_same_as
rdf_ RDF rdf_type
rdfs_ RDFS rdfs_label
cpov_ CPOV cpov_public_organisation
tooi_ TOOI tooi_overheidsorganisatie
bf_ BIBFRAME bf_title
edm_ Europeana edm_provided_cho

4. Migration Examples

Example 1: RiC-O Slots

# BEFORE (wrong)
rico_has_or_had_holder:
  slot_uri: rico:hasOrHadHolder
  range: string

# AFTER (correct)
record_holder:
  description: Reference to the custodian that holds or held this record set.
  slot_uri: rico:hasOrHadHolder
  exact_mappings:
    - rico:hasOrHadHolder
  range: Custodian

Example 2: SKOS Slots

# BEFORE (wrong)
skos_broader:
  slot_uri: skos:broader
  range: uriorcurie

# AFTER (correct)
broader_concept:
  description: A broader concept in the hierarchy.
  slot_uri: skos:broader
  exact_mappings:
    - skos:broader
  range: uriorcurie

Example 3: RiC-O Organizational Principle

# BEFORE (wrong)
rico_organizational_principle:
  slot_uri: rico:hasRecordSetType
  range: string

# AFTER (correct)
organizational_principle:
  description: The organizational principle (fonds, series, collection) for this record set.
  slot_uri: rico:hasRecordSetType
  exact_mappings:
    - rico:hasRecordSetType
  range: string

5. Exceptions

5.1 Identifier Slots

Slots that store identifiers from external systems may include system names (not ontology prefixes):

# ALLOWED: External system identifier
wikidata_id:
  description: Wikidata entity identifier (Q-number).
  slot_uri: schema:identifier
  range: string
  pattern: "^Q[0-9]+$"

# ALLOWED: External system identifier  
viaf_id:
  description: VIAF identifier for authority control.
  slot_uri: schema:identifier
  range: string

5.2 Internal Namespace Force Slots

Technical slots for namespace generation are prefixed with internal_:

# ALLOWED: Technical workaround slot
internal_wd_namespace_force:
  description: Internal slot to force WD namespace generation. Do not use.
  slot_uri: wd:Q35120
  range: string

6. Validation

Run this command to find violations:

cd schemas/20251121/linkml/modules/slots
ls -1 *.yaml | grep -E "^(rico_|skos_|schema_|dcterms_|dct_|prov_|org_|crm_|foaf_|owl_|rdf_|rdfs_|cpov_|tooi_|bf_|edm_)"

Expected output: No files (after migration)


7. Rationale

LinkML Best Practices

LinkML provides dedicated properties for ontology alignment:

Property Purpose Example
slot_uri Primary ontology predicate slot_uri: rico:hasOrHadHolder
exact_mappings Semantically equivalent predicates exact_mappings: [schema:holdingArchive]
close_mappings Nearly equivalent predicates close_mappings: [dc:creator]
related_mappings Related but different predicates related_mappings: [prov:wasAttributedTo]
narrow_mappings More specific predicates narrow_mappings: [rico:hasInstantiation]
broad_mappings More general predicates broad_mappings: [schema:about]

See: https://linkml.io/linkml-model/latest/docs/mappings/

Clean Separation of Concerns

  • Names: Human-readable, domain-focused terminology
  • URIs: Machine-readable, ontology-specific identifiers
  • Mappings: Cross-ontology alignment documentation

This separation allows:

  1. Renaming slots without changing ontology bindings
  2. Adding new ontology mappings without renaming slots
  3. Clear documentation of semantic relationships
  4. Easier maintenance and evolution

8. See Also