glam/.opencode/rules/class-files-no-inline-slots.md

140 lines
4.2 KiB
Markdown

# Rule 48: Class Files Must Not Define Inline Slots
🚨 **CRITICAL**: LinkML class files in `schemas/20251121/linkml/modules/classes/` MUST NOT define their own slots inline. All slots MUST be imported from the centralized `modules/slots/` directory.
## Problem Statement
When class files define their own slots (e.g., `AccessRestriction.yaml` defining its own slot properties), this creates:
1. **Duplication**: Same slot semantics defined in multiple places
2. **Inconsistency**: Slot definitions may diverge between files
3. **Frontend Issues**: LinkML viewer cannot properly render slot relationships
4. **Maintenance Burden**: Changes require updates in multiple locations
## Architecture Requirement
```
schemas/20251121/linkml/
├── modules/
│ ├── classes/ # Class definitions ONLY
│ │ └── *.yaml # NO inline slot definitions
│ ├── slots/ # ALL slot definitions go here
│ │ └── *.yaml # One file per slot or logical group
│ └── enums/ # Enumeration definitions
```
## Correct Pattern
**Class file** (`modules/classes/AccessRestriction.yaml`):
```yaml
id: https://nde.nl/ontology/hc/class/AccessRestriction
name: AccessRestriction
prefixes:
hc: https://nde.nl/ontology/hc/
linkml: https://w3id.org/linkml/
imports:
- linkml:types
- ../slots/restriction_type # Import slot from centralized location
- ../slots/restriction_reason
- ../slots/applies_from
- ../slots/applies_until
default_range: string
classes:
AccessRestriction:
class_uri: hc:AccessRestriction
description: >-
Describes access restrictions on heritage collections or items.
slots:
- restriction_type # Reference slot by name
- restriction_reason
- applies_from
- applies_until
```
**Slot file** (`modules/slots/restriction_type.yaml`):
```yaml
id: https://nde.nl/ontology/hc/slot/restriction_type
name: restriction_type
prefixes:
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
linkml: https://w3id.org/linkml/
imports:
- linkml:types
slots:
restriction_type:
slot_uri: hc:restrictionType
description: The type of access restriction applied.
range: string
exact_mappings:
- schema:accessMode
```
## Anti-Pattern (WRONG)
**DO NOT** define slots inline in class files:
```yaml
# WRONG - AccessRestriction.yaml with inline slots
classes:
AccessRestriction:
slots:
- restriction_type
slots: # ❌ DO NOT define slots here
restriction_type:
description: Type of restriction
range: string
```
## Identifying Violations
To find class files that incorrectly define slots:
```bash
# Find class files with inline slot definitions
grep -l "^slots:" schemas/20251121/linkml/modules/classes/*.yaml
```
Files that match need refactoring:
1. Extract slot definitions to `modules/slots/`
2. Add imports for the extracted slots
3. Remove inline `slots:` section from class file
## Known Violations to Fix
The following class files have been identified as defining their own slots and require refactoring:
- `AccessRestriction.yaml` - visible at https://nde.nl/ontology/hc/class/AccessRestriction
- (Add others as discovered)
## Migration Workflow
1. **Identify inline slots** in class file
2. **Check if slot exists** in `modules/slots/`
3. **If exists**: Remove inline definition, add import
4. **If not exists**: Create new slot file in `modules/slots/`, then add import
5. **Validate**: Run `linkml-validate` to ensure schema integrity
6. **Update manifest**: Regenerate `manifest.json` if needed
## Rationale
- **Single Source of Truth**: Each slot defined exactly once
- **Reusability**: Slots can be used across multiple classes
- **Frontend Compatibility**: LinkML viewer depends on centralized slots for proper edge rendering in UML diagrams
- **Semantic Consistency**: `slot_uri` and mappings defined once, applied everywhere
- **Maintenance**: Changes to slot semantics applied in one place
## See Also
- Rule 38: Slot Centralization and Semantic URI Requirements
- Rule: Slot Naming Convention (Current Style)
- Rule 42: No Ontology Prefixes in Slot Names
- Rule 43: Slot Nouns Must Be Singular