glam/.opencode/rules/linkml/slot-usage-minimization-rule.md
kempersc 6e63465196 Add ImageTilingServiceEndpoint class and archive ID class
- Introduced the ImageTilingServiceEndpoint class for tiled high-resolution image delivery, including deep-zoom and transformation capabilities, with multilingual descriptions and structured aliases.
- Archived the ID class as a backwards-compatible alias for Identifier, marking it as deprecated to enforce the use of the canonical Identifier model.
2026-02-15 21:40:13 +01:00

6.3 KiB

Rule 49: Slot Usage Minimization - No Redundant Overrides

Summary

LinkML slot_usage entries MUST provide meaningful modifications to the generic slot definition. Redundant slot_usage entries that merely re-declare the same values as the generic slot MUST be removed.

Background

What is slot_usage?

In LinkML, slot_usage allows a class to customize how an inherited slot behaves within that specific class context. It enables:

  • Narrowing the range to a more specific type
  • Adding class-specific required, multivalued, or identifier constraints
  • Providing class-specific description, examples, or pattern overrides
  • Adding class-specific semantic mappings (exact_mappings, close_mappings, etc.)

The Problem

A code generation process created 874 redundant slot_usage entries across 374 class files that simply re-declare the same range and inlined values already defined in the generic slot:

# In modules/slots/template_specificity.yaml (GENERIC DEFINITION)
slots:
  template_specificity:
    slot_uri: hc:templateSpecificity
    range: TemplateSpecificityScores
    inlined: true

# In modules/classes/AdministrativeOffice.yaml (REDUNDANT OVERRIDE)
slot_usage:
  template_specificity:
    range: TemplateSpecificityScores  # Same as generic!
    inlined: true                      # Same as generic!

This creates:

  1. Visual noise in the schema viewer (slot_usage badge displayed when nothing is actually customized)
  2. Maintenance burden (changes to generic slot must be mirrored in 374 files)
  3. Semantic confusion (suggests customization where none exists)

The Rule

MUST Remove: Truly Redundant Overrides

A slot_usage entry is truly redundant and MUST be removed if:

  1. All properties match the generic slot definition exactly
  2. No additional properties are added (no extra examples, description, required, etc.)
# REDUNDANT - Remove this entire slot_usage entry
slot_usage:
  template_specificity:
    range: TemplateSpecificityScores
    inlined: true

MAY Keep: Description-Only Modifications

A slot_usage entry that ONLY modifies the description by adding articles or context MAY be kept if it provides semantic value by referring to a specific entity rather than a general concept.

Tolerated Example (adds definiteness):

# Generic slot
slots:
  has_or_had_record_set:
    description: Record sets associated with a custodian.
    range: RecordSet

# Class-specific slot_usage - TOLERABLE
slot_usage:
  has_or_had_record_set:
    description: The record sets held by this archive.  # "The" makes it definite

Rationale: "The record sets" (definite) vs "record sets" (indefinite) conveys that this class specifically requires/expects record sets, rather than merely allowing them. This is a semantic distinction in linguistic terms (definiteness marking).

MUST Keep: Meaningful Modifications

A slot_usage entry MUST be kept if it provides ANY of the following:

Modification Type Example
Range narrowing range: MuseumCollection (from generic Collection)
Required constraint required: true (when generic is optional)
Pattern override pattern: "^NL-.*" (Dutch ISIL codes only)
Examples addition Class-specific examples not in generic
Inlined change inlined: true when generic is false
Identifier designation identifier: true for primary key

Decision Matrix

Scenario Action
All properties match generic exactly REMOVE
Only range and/or inlined match generic REMOVE
Only description differs by adding articles TOLERATE (but consider removing)
description provides substantive new information KEEP
Any other property modified KEEP

Implementation

Cleanup Script

Use the following to identify and remove redundant overrides:

# scripts/cleanup_redundant_slot_usage.py
import yaml
import glob

SLOTS_TO_CHECK = ['template_specificity', 'specificity_annotation']

for class_file in glob.glob('schemas/20251121/linkml/modules/classes/*.yaml'):
    with open(class_file) as f:
        content = yaml.safe_load(f)
    
    modified = False
    for cls_name, cls_def in content.get('classes', {}).items():
        slot_usage = cls_def.get('slot_usage', {})
        for slot_name in SLOTS_TO_CHECK:
            if slot_name in slot_usage:
                override = slot_usage[slot_name]
                # Check if redundant (only range/inlined matching generic)
                if is_redundant(override, slot_name):
                    del slot_usage[slot_name]
                    modified = True
        
        # Remove empty slot_usage
        if not slot_usage:
            del cls_def['slot_usage']
    
    if modified:
        with open(class_file, 'w') as f:
            yaml.dump(content, f, allow_unicode=True, sort_keys=False)

Validation

After cleanup, validate that:

  1. linkml-validate passes for all schemas
  2. Generated RDF/OWL output is unchanged (redundant overrides have no semantic effect)
  3. Frontend slot viewer shows fewer slot_usage badges

Frontend UX Implications

The frontend LinkML viewer should:

  1. Display "Slot Usage" (with space, no underscore) instead of slot_usage
  2. Add tooltip explaining what slot_usage means, linking to LinkML documentation
  3. Only show badge when slot_usage contains meaningful modifications
  4. Comparison view should highlight actual differences, not redundant re-declarations

Affected Slots

Current analysis found redundant overrides for:

Slot Redundant Overrides Files Affected
template_specificity 873 374
specificity_annotation 874 374

References

Version History

Date Change
2026-01-12 Initial rule created after identifying 874 redundant slot_usage entries