Refactor schema slots to resolve OWL ambiguity and enhance flexibility

- Updated ranges for multiple slots from `string` to `uriorcurie` to address OWL "Ambiguous type" warnings and allow for URI/CURIE references.
- Removed specialized slots for subtitle and transcript formats, consolidating them under broader predicates.
- Introduced new slots for structured descriptions, observation source documents, and entity statuses to improve data modeling.
- Implemented Rule 54 to broaden generic predicate ranges instead of creating bespoke predicates, promoting schema reuse and reducing complexity.
- Added a script for generating OWL ontology with type-object handling to ensure consistent ObjectProperty treatment for polymorphic slots.
This commit is contained in:
kempersc 2026-01-16 15:06:36 +01:00
parent 0a1f6c6f34
commit db389ed0a3
68 changed files with 1522 additions and 434 deletions

View file

@ -0,0 +1,179 @@
# Rule 54: Broaden Generic Predicate Ranges Instead of Creating Bespoke Predicates
🚨 **CRITICAL**: When fixing gen-owl "Ambiguous type" warnings, **broaden the range of generic predicates** rather than creating specialized bespoke predicates.
## The Problem
gen-owl "Ambiguous type" warnings occur when a slot is used as both:
- **DatatypeProperty** (base range: `string`, `integer`, `uri`, etc.)
- **ObjectProperty** (slot_usage override range: a class like `Description`, `SubtitleFormatEnum`)
This creates OWL ambiguity because OWL requires properties to be either DatatypeProperty OR ObjectProperty, not both.
## ❌ WRONG Approach: Create Bespoke Predicates
```yaml
# DON'T DO THIS - creates proliferation of rare-use predicates
slots:
has_or_had_subtitle_format: # Only used by VideoSubtitle
range: SubtitleFormatEnum
has_or_had_transcript_format: # Only used by VideoTranscript
range: TranscriptFormat
```
**Why This Is Wrong**:
- Creates **predicate proliferation** (schema bloat)
- Bespoke predicates are **rarely reused** across classes
- **Increases cognitive load** for schema users
- **Fragments the ontology** unnecessarily
- Violates the principle of schema parsimony
## ✅ CORRECT Approach: Broaden Generic Predicate Ranges
```yaml
# DO THIS - make the generic predicate flexible enough
slots:
has_or_had_format:
range: uriorcurie # Broadened from string
description: |
The format of a resource. Classes narrow this to specific
enum types (SubtitleFormatEnum, TranscriptFormatEnum) via slot_usage.
```
Then in class files, use `slot_usage` to narrow the range:
```yaml
classes:
VideoSubtitle:
slots:
- has_or_had_format
slot_usage:
has_or_had_format:
range: SubtitleFormatEnum # Narrowed for this class
required: true
```
## Range Broadening Options
| Original Range | Broadened Range | When to Use |
|----------------|-----------------|-------------|
| `string` | `uriorcurie` | When class overrides use URI-identified types or enums |
| `string` | `Any` | When truly polymorphic (strings AND class instances) |
| Specific class | Common base class | When multiple subclasses are used |
## Decision Tree
```
gen-owl warning: "Ambiguous type for: SLOTNAME"
Is base slot range a primitive (string, integer, uri)?
├─ YES → Broaden to uriorcurie or Any
│ - Edit modules/slots/SLOTNAME.yaml
│ - Change range: string → range: uriorcurie
│ - Document change with Rule 54 reference
│ - Keep class-level slot_usage overrides (they narrow the range)
└─ NO → Consider if base slot needs common ancestor class
- Create abstract base class if needed
- Or broaden to uriorcurie
```
## Implementation Workflow
1. **Identify warning**: `gen-owl ... 2>&1 | grep "Ambiguous type for:"`
2. **Check base slot range**:
```bash
cat modules/slots/SLOTNAME.yaml | grep -A5 "^slots:" | grep "range:"
```
3. **Find class overrides**:
```bash
for f in modules/classes/*.yaml; do
grep -l "SLOTNAME" "$f" && grep -A3 "SLOTNAME:" "$f" | grep "range:"
done
```
4. **Broaden base range**:
- Edit `modules/slots/SLOTNAME.yaml`
- Change `range: string``range: uriorcurie`
- Add annotation documenting the change
5. **Verify fix**: Run gen-owl and confirm warning is gone
6. **Keep slot_usage overrides**: Class-level range narrowing is fine and expected
## Examples
### Example 1: has_or_had_format
**Before (caused warning)**:
```yaml
# Base slot
slots:
has_or_had_format:
range: string # DatatypeProperty
# Class override
classes:
VideoSubtitle:
slot_usage:
has_or_had_format:
range: SubtitleFormatEnum # ObjectProperty → CONFLICT!
```
**After (fixed)**:
```yaml
# Base slot - broadened
slots:
has_or_had_format:
range: uriorcurie # Now ObjectProperty-compatible
# Class override - unchanged, still narrows
classes:
VideoSubtitle:
slot_usage:
has_or_had_format:
range: SubtitleFormatEnum # Valid narrowing
```
### Example 2: has_or_had_hypernym
**Before**: `range: string` (DatatypeProperty)
**After**: `range: uriorcurie` (ObjectProperty-compatible)
Classes that override to class ranges now work without ambiguity.
## Validation
After broadening, run:
```bash
gen-owl 01_custodian_name_modular.yaml 2>&1 | grep "Ambiguous type for: SLOTNAME"
```
The warning should disappear without creating new predicates.
## Anti-Patterns to Avoid
| ❌ Anti-Pattern | ✅ Correct Pattern |
|----------------|-------------------|
| Create `has_or_had_subtitle_format` | Broaden `has_or_had_format` to `uriorcurie` |
| Create `has_or_had_entity_type` | Broaden `has_or_had_type` to `uriorcurie` |
| Create `has_or_had_X_label` | Broaden `has_or_had_label` to `uriorcurie` |
| Create `has_or_had_X_status` | Broaden `has_or_had_status` to `uriorcurie` |
## Rationale
This approach:
1. **Reduces schema complexity** - Fewer predicates to understand
2. **Promotes reuse** - Generic predicates work across domains
3. **Maintains OWL consistency** - Single property type per predicate
4. **Preserves type safety** - slot_usage still enforces class-specific ranges
5. **Follows semantic web best practices** - Broad predicates, narrow contexts
## See Also
- Rule 38: Slot Centralization and Semantic URI Requirements
- Rule 39: Slot Naming Convention (RiC-O Style)
- Rule 49: Slot Usage Minimization
- LinkML Documentation: [slot_usage](https://linkml.io/linkml-model/latest/docs/slot_usage/)

View file

@ -47,7 +47,7 @@ This is NOT a simple data extraction project. This is an **ontology engineering
---
This section summarizes 54 critical rules. Each rule has complete documentation in `.opencode/` files.
This section summarizes 55 critical rules. Each rule has complete documentation in `.opencode/` files.
### Rule 0: LinkML Schemas Are the Single Source of Truth
@ -1735,6 +1735,64 @@ from .provenance import ProvenanceTracker
---
### Rule 55: Broaden Generic Predicate Ranges Instead of Creating Bespoke Predicates
🚨 **CRITICAL**: When fixing gen-owl "Ambiguous type" warnings, **broaden the range of generic predicates** rather than creating specialized bespoke predicates.
**The Problem**: gen-owl warnings occur when a slot is used as both:
- **DatatypeProperty** (base range: `string`, `integer`, `uri`)
- **ObjectProperty** (slot_usage override range: a class like `SubtitleFormatEnum`)
**❌ WRONG Approach - Create Bespoke Predicates**:
```yaml
# DON'T DO THIS - creates proliferation of rare-use predicates
slots:
has_or_had_subtitle_format: # Only used by VideoSubtitle
range: SubtitleFormatEnum
has_or_had_transcript_format: # Only used by VideoTranscript
range: TranscriptFormat
```
**Why This Is Wrong**:
- Creates **predicate proliferation** (schema bloat)
- Bespoke predicates are **rarely reused**
- **Fragments the ontology** unnecessarily
**✅ CORRECT Approach - Broaden Generic Predicate Ranges**:
```yaml
# DO THIS - broaden the base slot range
slots:
has_or_had_format:
range: uriorcurie # Broadened from string
# Classes narrow via slot_usage (this is fine)
classes:
VideoSubtitle:
slot_usage:
has_or_had_format:
range: SubtitleFormatEnum # Valid narrowing
```
**Range Broadening Options**:
| Original Range | Broadened Range | When to Use |
|----------------|-----------------|-------------|
| `string` | `uriorcurie` | When class overrides use URI-identified types/enums |
| `string` | `Any` | When truly polymorphic (strings AND class instances) |
| Specific class | Common base class | When multiple subclasses are used |
**Implementation Workflow**:
1. Identify warning: `gen-owl ... 2>&1 | grep "Ambiguous type for:"`
2. Broaden base slot range: `range: string``range: uriorcurie`
3. Keep class-level slot_usage overrides (they narrow the range)
4. Verify fix: Run gen-owl and confirm warning is gone
**See**: `.opencode/rules/broaden-generic-predicate-ranges-rule.md` for complete documentation
---
## Appendix: Full Rule Content (No .opencode Equivalent)
The following rules have no separate .opencode file and are preserved in full:

View file

@ -1,12 +1,12 @@
{
"generated": "2026-01-16T13:33:06.596Z",
"generated": "2026-01-16T14:04:19.745Z",
"schemaRoot": "/schemas/20251121/linkml",
"totalFiles": 3007,
"totalFiles": 3010,
"categoryCounts": {
"main": 4,
"class": 818,
"enum": 152,
"slot": 2029,
"slot": 2032,
"module": 4
},
"categories": [
@ -9182,6 +9182,11 @@
"path": "modules/slots/has_or_had_domain.yaml",
"category": "slot"
},
{
"name": "has_or_had_entity_status",
"path": "modules/slots/has_or_had_entity_status.yaml",
"category": "slot"
},
{
"name": "has_or_had_environmental_condition",
"path": "modules/slots/has_or_had_environmental_condition.yaml",
@ -9447,6 +9452,11 @@
"path": "modules/slots/has_or_had_notes.yaml",
"category": "slot"
},
{
"name": "has_or_had_observation_source_document",
"path": "modules/slots/has_or_had_observation_source_document.yaml",
"category": "slot"
},
{
"name": "has_or_had_open_access_endpoint",
"path": "modules/slots/has_or_had_open_access_endpoint.yaml",
@ -9802,6 +9812,11 @@
"path": "modules/slots/has_or_had_strategic_objective.yaml",
"category": "slot"
},
{
"name": "has_or_had_structured_description",
"path": "modules/slots/has_or_had_structured_description.yaml",
"category": "slot"
},
{
"name": "has_or_had_sub_collection",
"path": "modules/slots/has_or_had_sub_collection.yaml",

View file

@ -11,7 +11,7 @@ imports:
# Shared slots (replacing catering_place_* slots per Rule 53)
- ../slots/has_or_had_identifier
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/has_or_had_structured_description
- ./Label
- ./Description
# Domain-specific slots (kept)
@ -82,7 +82,7 @@ classes:
- wd:Q30022
slots:
- has_or_had_accessibility_feature
- has_or_had_description # was: catering_place_description - migrated per Rule 53
- has_or_had_structured_description # was: catering_place_description - migrated per Rule 53
- has_or_had_identifier # was: catering_place_id - migrated per Rule 53
- has_or_had_label # was: catering_place_name - migrated per Rule 53
- catering_price_range
@ -128,7 +128,7 @@ classes:
- value:
label_text: Van Gogh Museum Café
description: Museum café
has_or_had_description: # was: catering_place_description - migrated per Rule 53
has_or_had_structured_description: # was: catering_place_description - migrated per Rule 53
range: Description
inlined: true
description: A description of the catering place.
@ -261,7 +261,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/rijksmuseum-restaurant
has_or_had_label:
label_text: RIJKS Restaurant
has_or_had_description:
has_or_had_structured_description:
description_text: Michelin-starred restaurant serving modern Dutch cuisine. Located in museum atrium with garden views.
catering_type: RESTAURANT
cuisine_type: Modern Dutch fine dining
@ -280,7 +280,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/na-cafe
has_or_had_label:
label_text: Nationaal Archief Café
has_or_had_description:
has_or_had_structured_description:
description_text: Casual café for archive visitors. Light lunches, coffee, and pastries.
catering_type: CAFE
cuisine_type: Café fare, sandwiches, soups
@ -296,7 +296,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/cafe-americain
has_or_had_label:
label_text: Café Americain
has_or_had_description:
has_or_had_structured_description:
description_text: Historic art deco café dating from 1902. Literary landmark and protected monument.
catering_type: HISTORIC_CAFE
heritage_type_classification: HISTORIC_RESTAURANT

View file

@ -19,7 +19,7 @@ imports:
# MIGRATED 2026-01-15: lab_* slots replaced with shared slots per Rule 53
- ../slots/has_or_had_identifier # was: lab_id
- ../slots/has_or_had_label # was: lab_name
- ../slots/has_or_had_description # was: lab_description
- ../slots/has_or_had_structured_description # was: lab_description
- ./Label
- ./Description
- ../slots/safety_certification
@ -90,7 +90,7 @@ classes:
# MIGRATED 2026-01-15: lab_* slots replaced with shared slots per Rule 53
- has_or_had_identifier # was: lab_id
- has_or_had_label # was: lab_name
- has_or_had_description # was: lab_description
- has_or_had_structured_description # was: lab_description
- safety_certification
- specificity_annotation
- staff_count
@ -126,7 +126,7 @@ classes:
- value:
label_text: KB Preservation Laboratory
description: Library preservation lab
has_or_had_description: # was: lab_description
has_or_had_structured_description: # was: lab_description
range: Description
inlined: true
description: >-
@ -233,7 +233,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/rijksmuseum-conservation
has_or_had_label:
label_text: Rijksmuseum Conservation Studio
has_or_had_description:
has_or_had_structured_description:
description_text: State-of-the-art conservation studio specializing in Dutch Golden Age paintings, works on paper, and decorative arts.
conservation_specialization:
- Paintings
@ -258,7 +258,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/na-restauratie
has_or_had_label:
label_text: Nationaal Archief Restauratie Atelier
has_or_had_description:
has_or_had_structured_description:
description_text: Paper and parchment conservation workshop serving the national archives. Specializes in historical documents, maps, and seals.
conservation_specialization:
- Paper

View file

@ -221,7 +221,6 @@ classes:
range: string
required: false
legal_status:
range: uriorcurie
required: false
place_designation:
range: CustodianPlace

View file

@ -48,7 +48,7 @@ imports:
- ../slots/dissolution_date
- ../slots/temporal_extent
- ../slots/is_or_was_suborganization_of # was: parent_custodian - migrated per Rule 53 (2025-01-15)
- ../slots/legal_status
- ../slots/has_or_had_entity_status
- ../slots/governance_structure
- ../slots/reconstruction_method
- ../slots/is_or_was_derived_from # was: was_derived_from - migrated per Rule 53
@ -117,7 +117,7 @@ classes:
- legal_form
- legal_jurisdiction
- legal_name
- legal_status
- has_or_had_entity_status
- is_or_was_suborganization_of # was: parent_custodian - migrated per Rule 53 (2025-01-15)
- primary_register
- reconstruction_method
@ -231,7 +231,7 @@ classes:
description: |
Parent organization in hierarchical structure.
MIGRATED from parent_custodian slot per slot_fixes.yaml (Rule 53, 2025-01-15).
legal_status:
has_or_had_entity_status:
range: LegalStatus
required: true
examples:
@ -353,7 +353,7 @@ classes:
alpha_2: NL
alpha_3: NLD
legal_system_type: CIVIL_LAW
legal_status:
has_or_had_entity_status:
status_code: ACTIVE
status_name: Active
is_or_was_derived_from: # was: was_derived_from - migrated per Rule 53

View file

@ -199,7 +199,6 @@ classes:
- https://nde.nl/ontology/hc/collection/na-colonial-maps
description: Collections managed by Colonial Records Dept
located_at:
range: uriorcurie
examples:
- value: https://nde.nl/ontology/hc/aux-place/nationaal-archief-building-b
description: Department located in Building B

View file

@ -16,7 +16,7 @@ imports:
# Shared slots (replacing education_center_* slots per Rule 53)
- ../slots/has_or_had_identifier
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/has_or_had_structured_description
- ./Label
- ./Description
# Domain-specific slots (kept)
@ -95,7 +95,7 @@ classes:
# MIGRATED 2026-01-15: education_center_* slots replaced with shared slots per Rule 53
- has_or_had_identifier # was: education_center_id
- has_or_had_label # was: education_center_name
- has_or_had_description # was: education_center_description
- has_or_had_structured_description # was: education_center_description
- education_contact_email
- education_type_classification
- has_av_equipment
@ -135,7 +135,7 @@ classes:
- value: |
label_text: KB Workshops & Trainingen
description: Library education facility
has_or_had_description:
has_or_had_structured_description:
range: Description
inlined: true
description: A description of the education center.
@ -274,7 +274,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/rijksmuseum-education
has_or_had_label:
label_text: Rijksmuseum Educatie Centrum
has_or_had_description:
has_or_had_structured_description:
description_text: Dedicated education facility offering school programs, family workshops, and teacher training.
education_type_classification: EDUCATION_CENTER
serves_or_served: # was: target_audience - migrated per Rule 53
@ -306,7 +306,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/na-leercentrum
has_or_had_label:
label_text: Nationaal Archief Leercentrum
has_or_had_description:
has_or_had_structured_description:
description_text: Learning center focused on historical research skills and genealogy.
education_type_classification: RESOURCE_CENTER
serves_or_served: # was: target_audience - migrated per Rule 53

View file

@ -12,7 +12,7 @@ imports:
# Shared slots (replacing exhibition_space_* slots per Rule 53)
- ../slots/has_or_had_identifier
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/has_or_had_structured_description
- ./Label
- ./Description
# Domain-specific slots (kept)
@ -89,7 +89,7 @@ classes:
# MIGRATED 2026-01-15: exhibition_space_* slots replaced with shared slots per Rule 53
- has_or_had_identifier # was: exhibition_space_id
- has_or_had_label # was: exhibition_space_name
- has_or_had_description # was: exhibition_space_description
- has_or_had_structured_description # was: exhibition_space_description
- exhibition_type
- gallery_type_classification
- has_climate_control
@ -128,7 +128,7 @@ classes:
- value: |
label_text: Van Gogh Museum Mesdag Collection
description: Partner venue exhibition
has_or_had_description:
has_or_had_structured_description:
range: Description
inlined: true
description: A description of the exhibition space.
@ -239,7 +239,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/rijksmuseum-schiphol-gallery
has_or_had_label:
label_text: Rijksmuseum Schiphol
has_or_had_description:
has_or_had_structured_description:
description_text: Free gallery at Schiphol Airport featuring rotating highlights from the Rijksmuseum collection.
exhibition_type: SATELLITE_GALLERY
museum_type_classification: ART_MUSEUM
@ -259,7 +259,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/stedelijk-project-space
has_or_had_label:
label_text: Stedelijk Museum Bureau Amsterdam
has_or_had_description:
has_or_had_structured_description:
description_text: Project space for emerging contemporary artists and experimental exhibitions.
exhibition_type: PROJECT_SPACE
gallery_type_classification: PROJECT_SPACE

View file

@ -27,7 +27,7 @@ imports:
# MIGRATED 2026-01-15: shop_* slots replaced with shared slots per Rule 53
- ../slots/has_or_had_identifier # was: shop_id
- ../slots/has_or_had_label # was: shop_name
- ../slots/has_or_had_description # was: shop_description
- ../slots/has_or_had_structured_description # was: shop_description
- ./Label
- ./Description
- ../slots/shop_type
@ -86,7 +86,7 @@ classes:
\ - Temporary retail for special exhibition\n - Exhibition catalog, themed merchandise\n\n**Example - Rijksmuseum\
\ Gift Shop**:\n```yaml\nCustodian:\n hc_id: \"https://nde.nl/ontology/hc/nl-nh-ams-m-rm-q190804\"\n preferred_label:\
\ \"Rijksmuseum\"\n gift_shop:\n - has_or_had_identifier: \"https://nde.nl/ontology/hc/gift-shop/rijksmuseum-shop\" # was: shop_id\n has_or_had_label: # was: shop_name\n label_text:\
\ \"Rijksmuseum Shop\"\n shop_type: MUSEUM_SHOP\n has_or_had_description: # was: shop_description\n description_text: |\n Award-winning museum shop offering\
\ \"Rijksmuseum Shop\"\n shop_type: MUSEUM_SHOP\n has_or_had_structured_description: # was: shop_description\n description_text: |\n Award-winning museum shop offering\
\ reproductions, design objects,\n books, and exclusive Rijksmuseum merchandise.\n physical_location:\n\
\ - place_name: \"Rijksmuseum Shop - Main Hall\"\n auxiliary_place_type: RETAIL_SPACE\n street_address:\
\ \"Museumstraat 1, Amsterdam\"\n online_shop:\n - platform_name: \"Rijksmuseum Online Shop\"\n \
@ -122,7 +122,7 @@ classes:
# MIGRATED 2026-01-15: shop_* slots replaced with shared slots per Rule 53
- has_or_had_identifier # was: shop_id
- has_or_had_label # was: shop_name
- has_or_had_description # was: shop_description
- has_or_had_structured_description # was: shop_description
- shop_type
- specificity_annotation
- square_meters
@ -155,7 +155,7 @@ classes:
- value:
label_text: British Library Bookshop
description: Library bookshop name
has_or_had_description: # was: shop_description
has_or_had_structured_description: # was: shop_description
range: Description
inlined: true
description: A description of the gift shop.
@ -334,7 +334,7 @@ classes:
has_or_had_label: # was: shop_name
label_text: Rijksmuseum Shop
shop_type: MUSEUM_SHOP
has_or_had_description: # was: shop_description
has_or_had_structured_description: # was: shop_description
description_text: Award-winning museum shop offering reproductions, design objects, books, and exclusive Rijksmuseum merchandise. Located in the redesigned entrance hall.
physical_location:
- place_name: Rijksmuseum Shop - Main Hall
@ -377,7 +377,7 @@ classes:
has_or_had_label: # was: shop_name
label_text: British Library Shop
shop_type: BOOKSHOP
has_or_had_description: # was: shop_description
has_or_had_structured_description: # was: shop_description
description_text: Specialist bookshop focusing on rare book facsimiles, literary merchandise, and British Library publications.
physical_location:
- place_name: British Library Shop
@ -410,7 +410,7 @@ classes:
has_or_had_label: # was: shop_name
label_text: Vermeer Exhibition Pop-up Shop
shop_type: POP_UP
has_or_had_description: # was: shop_description
has_or_had_structured_description: # was: shop_description
description_text: Temporary retail for the 2023 Vermeer exhibition with exclusive exhibition merchandise and catalog.
physical_location:
- place_name: Vermeer Exhibition Shop

View file

@ -65,7 +65,7 @@ classes:
description: Phone number
website:
slot_uri: hc:hasWebsite
range: string
range: uri # FIXED 2026-01-16: was string, changed to uri for consistency
description: Website URL (may be domain only)
close_mappings:
- schema:url

View file

@ -21,7 +21,7 @@ imports:
# MIGRATED 2026-01-15: heritage_form_* slots replaced with shared slots per Rule 53
- ../slots/has_or_had_identifier # was: heritage_form_id
- ../slots/has_or_had_label # was: heritage_form_name
- ../slots/has_or_had_description # was: heritage_form_description
- ../slots/has_or_had_structured_description # was: heritage_form_description
- ./Label
- ./Description
- ../slots/kien_registration_date
@ -139,7 +139,7 @@ classes:
- external_link
- geographic_scope
# MIGRATED 2026-01-15: heritage_form_* slots replaced with shared slots per Rule 53
- has_or_had_description # was: heritage_form_description
- has_or_had_structured_description # was: heritage_form_description
- has_or_had_identifier # was: heritage_form_id
- has_or_had_label # was: heritage_form_name
- kien_registration_date
@ -197,7 +197,7 @@ classes:
label_text: 1 aprilviering Brielle
- value:
label_text: Bloemencorso Bollenstreek
has_or_had_description: # was: heritage_form_description
has_or_had_structured_description: # was: heritage_form_description
required: false
range: Description
inlined: true
@ -388,7 +388,7 @@ classes:
label: "Pride Amsterdam"
has_or_had_label:
label_text: Pride Amsterdam
has_or_had_description:
has_or_had_structured_description:
description_text: "Annual LGBTQ+ celebration featuring the Canal Parade through Amsterdam's historic canals. First held in 1996, it represents Dutch values of tolerance, equality, and freedom."
# unesco_domain - MIGRATED to is_or_was_categorized_as (2026-01-14, Rule 53)
is_or_was_categorized_as:

View file

@ -42,6 +42,7 @@ imports:
- ../slots/role_start_date
- ../slots/role_end_date
- ../slots/observation_source
- ../slots/has_or_had_observation_source_document
- ../slots/is_or_was_affected_by_event
- ../slots/contact_email
- ../slots/expertise_area
@ -126,6 +127,7 @@ classes:
- linkedin_profile_url
- modified
- observation_source
- has_or_had_observation_source_document
- occupation
- person_name
- pronoun
@ -246,8 +248,13 @@ classes:
range: date
required: false
observation_source:
range: string
required: false
description: Simple text reference to source (use has_or_had_observation_source_document for structured data)
has_or_had_observation_source_document:
range: SourceDocument
required: false
inlined: true
is_or_was_affected_by_event:
range: OrganizationalChangeEvent
required: false

View file

@ -36,7 +36,7 @@ imports:
- ../slots/event_timespan
- ../slots/footnote
- ../slots/from_owner
# REMOVED 2026-01-15: from_owner_text - migrated to has_or_had_description (Rule 53, symmetry with to_owner_text)
# REMOVED 2026-01-15: from_owner_text - migrated to has_or_had_structured_description (Rule 53, symmetry with to_owner_text)
- ../slots/lot_number
- ../slots/nazi_era_flag
- ../slots/price_text
@ -44,8 +44,7 @@ imports:
- ../slots/specificity_annotation
- ../slots/template_specificity
- ../slots/to_owner
- ../slots/has_or_had_description # was: to_owner_text - migrated per Rule 53 (2026-01-15)
- ./Description # for has_or_had_description range
- ../slots/has_or_had_structured_description # was: to_owner_text - migrated per Rule 53 (2026-01-15)
# REMOVED 2026-01-15: transfer_location, transfer_location_text - migrated to event_location (Rule 53)
- ../slots/event_location
- ./SpecificityAnnotation
@ -96,7 +95,7 @@ classes:
- event_type
- footnote
- from_owner
# MIGRATED 2026-01-15: from_owner_text → has_or_had_description (Rule 53, symmetry with to_owner_text)
# MIGRATED 2026-01-15: from_owner_text → has_or_had_structured_description (Rule 53, symmetry with to_owner_text)
- lot_number
- nazi_era_flag
- object_ref
@ -108,7 +107,7 @@ classes:
- specificity_annotation
- template_specificity
- to_owner
- has_or_had_description # was: to_owner_text - migrated per Rule 53 (2026-01-15)
- has_or_had_structured_description # was: to_owner_text - migrated per Rule 53 (2026-01-15)
# MIGRATED 2026-01-15: transfer_location, transfer_location_text → event_location (Rule 53)
- event_location
slot_usage:
@ -169,7 +168,7 @@ classes:
inlined: false
examples:
- value: https://nde.nl/ontology/hc/custodian/nl/mauritshuis
has_or_had_description: # was: to_owner_text, from_owner_text - migrated per Rule 53 (2026-01-15)
has_or_had_structured_description: # was: to_owner_text, from_owner_text - migrated per Rule 53 (2026-01-15)
description: |
Owner (source or destination) described as text when no structured entity exists.
MIGRATED from to_owner_text and from_owner_text per slot_fixes.yaml (Rule 53, 2026-01-15).
@ -178,9 +177,7 @@ classes:
- "from_owner": Previous owner (source of transfer)
- "to_owner": New owner (destination of transfer)
required: false
range: Description
multivalued: true
inlined: true
examples:
# from_owner examples (migrated from from_owner_text)
- value:
@ -361,8 +358,8 @@ classes:
event_timespan:
begin_of_the_begin: '1664-01-01'
end_of_the_end: '1667-12-31'
# MIGRATED 2026-01-15: to_owner_text, from_owner_text → has_or_had_description (Rule 53)
has_or_had_description:
# MIGRATED 2026-01-15: to_owner_text, from_owner_text → has_or_had_structured_description (Rule 53)
has_or_had_structured_description:
- description_text: Johannes Vermeer, Delft
description_type: to_owner
# MIGRATED 2026-01-15: transfer_location_text → event_location (Rule 53)
@ -377,8 +374,8 @@ classes:
object_ref: https://nde.nl/ontology/hc/object/mauritshuis-girl-pearl-earring
event_type: PURCHASE
event_date_text: c. 1665-1674
# MIGRATED 2026-01-15: from_owner_text, to_owner_text → has_or_had_description (Rule 53)
has_or_had_description:
# MIGRATED 2026-01-15: from_owner_text, to_owner_text → has_or_had_structured_description (Rule 53)
has_or_had_structured_description:
- description_text: Johannes Vermeer
description_type: from_owner
- description_text: Pieter van Ruijven, Delft (c. 1665-1674)
@ -395,8 +392,8 @@ classes:
event_type: AUCTION
event_date: '1696-05-16'
event_date_text: May 16, 1696
# MIGRATED 2026-01-15: from_owner_text, to_owner_text → has_or_had_description (Rule 53)
has_or_had_description:
# MIGRATED 2026-01-15: from_owner_text, to_owner_text → has_or_had_structured_description (Rule 53)
has_or_had_structured_description:
- description_text: Estate of Jacob Dissius
description_type: from_owner
- description_text: Unknown buyer
@ -421,8 +418,8 @@ classes:
event_type: PURCHASE
event_date: '1881-01-01'
event_date_text: '1881'
# MIGRATED 2026-01-15: from_owner_text, to_owner_text → has_or_had_description (Rule 53)
has_or_had_description:
# MIGRATED 2026-01-15: from_owner_text, to_owner_text → has_or_had_structured_description (Rule 53)
has_or_had_structured_description:
- description_text: Unknown seller
description_type: from_owner
- description_text: A.A. des Tombe, The Hague
@ -442,8 +439,8 @@ classes:
event_type: BEQUEST
event_date: '1903-01-01'
event_date_text: '1903'
# MIGRATED 2026-01-15: from_owner_text → has_or_had_description (Rule 53)
has_or_had_description:
# MIGRATED 2026-01-15: from_owner_text → has_or_had_structured_description (Rule 53)
has_or_had_structured_description:
- description_text: A.A. des Tombe (d. 1903)
description_type: from_owner
- description_text: Mauritshuis, The Hague
@ -460,8 +457,8 @@ classes:
object_ref: https://nde.nl/ontology/hc/object/example-painting
event_type: CONFISCATION
event_date_text: '1938'
# MIGRATED 2026-01-15: from_owner_text, to_owner_text → has_or_had_description (Rule 53)
has_or_had_description:
# MIGRATED 2026-01-15: from_owner_text, to_owner_text → has_or_had_structured_description (Rule 53)
has_or_had_structured_description:
- description_text: Jewish collector, Vienna
description_type: from_owner
- description_text: Nazi authorities

View file

@ -99,7 +99,9 @@ classes:
multivalued: true
inlined_as_list: true
description: Manual research source records
website:
# RENAMED 2026-01-16: website → website_source to resolve OWL ambiguous type warning
# (website is used elsewhere with range: uri, here it's range: SourceRecord)
website_source:
slot_uri: hc:hasWebsiteSource
range: SourceRecord
multivalued: true

View file

@ -10,7 +10,7 @@ imports:
# MIGRATED 2026-01-15: reading_room_* slots replaced with shared slots per Rule 53
- ../slots/has_or_had_identifier # was: reading_room_id
- ../slots/has_or_had_label # was: reading_room_name
- ../slots/has_or_had_description # was: reading_room_description
- ../slots/has_or_had_structured_description # was: reading_room_description
- ./Label
- ./Description
- ../slots/reading_room_type
@ -88,7 +88,7 @@ classes:
- has_wifi
- opening_hour
# MIGRATED 2026-01-15: reading_room_* slots replaced with shared slots per Rule 53
- has_or_had_description # was: reading_room_description
- has_or_had_structured_description # was: reading_room_description
- has_or_had_identifier # was: reading_room_id
- has_or_had_label # was: reading_room_name
- reading_room_type
@ -126,7 +126,7 @@ classes:
- value:
label_text: Stadsarchief Amsterdam Studiezaal
description: City archive reading room
has_or_had_description: # was: reading_room_description
has_or_had_structured_description: # was: reading_room_description
range: Description
inlined: true
description: A description of the reading room.
@ -253,7 +253,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/na-studiezaal
has_or_had_label:
label_text: Nationaal Archief Studiezaal
has_or_had_description:
has_or_had_structured_description:
description_text: Main research room for consulting archival collections. Self-service retrieval from open stacks. Staff assistance available.
reading_room_type: GENERAL
seating_capacity: 80
@ -277,7 +277,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/kb-bijzondere-collecties
has_or_had_label:
label_text: KB Bijzondere Collecties Leeszaal
has_or_had_description:
has_or_had_structured_description:
description_text: Special collections reading room for rare books, manuscripts, and incunabula. Supervised handling required.
reading_room_type: SPECIAL_COLLECTIONS
seating_capacity: 20

View file

@ -20,7 +20,7 @@ imports:
# MIGRATED 2026-01-15: research_center_* slots replaced with shared slots per Rule 53
- ../slots/has_or_had_identifier # was: research_center_id
- ../slots/has_or_had_label # was: research_center_name
- ../slots/has_or_had_description # was: research_center_description
- ../slots/has_or_had_structured_description # was: research_center_description
- ./Label
- ./Description
- ../slots/research_center_type
@ -89,7 +89,7 @@ classes:
- major_research_project
- publication_series_name
# MIGRATED 2026-01-15: research_center_* slots replaced with shared slots per Rule 53
- has_or_had_description # was: research_center_description
- has_or_had_structured_description # was: research_center_description
- has_or_had_identifier # was: research_center_id
- has_or_had_label # was: research_center_name
- research_center_type
@ -124,7 +124,7 @@ classes:
- value:
label_text: NIOD Institute for War, Holocaust and Genocide Studies
description: Specialized research institute
has_or_had_description: # was: research_center_description
has_or_had_structured_description: # was: research_center_description
range: Description
inlined: true
description: A description of the research center.
@ -236,7 +236,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/rijksmuseum-research
has_or_had_label:
label_text: Rijksmuseum Research Department
has_or_had_description:
has_or_had_structured_description:
description_text: Scholarly research on Dutch art and history, with focus on Golden Age. Publishes Rijksmuseum Bulletin and monograph series.
research_center_type: RESEARCH_DEPARTMENT
research_focus_area:
@ -269,7 +269,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/kb-dh-lab
has_or_had_label:
label_text: KB Lab - Digital Humanities
has_or_had_description:
has_or_had_structured_description:
description_text: Digital humanities research facility focusing on computational approaches to library collections.
research_center_type: DIGITAL_HUMANITIES_CENTER
research_focus_area:

View file

@ -50,8 +50,7 @@ imports:
- ../slots/specificity_annotation
- ../slots/standards_applied
- ../slots/has_or_had_storage_condition
- ../slots/has_or_had_description # was: storage_description - migrated per Rule 53
- ./Description
- ../slots/has_or_had_structured_description # was: storage_description - migrated per Rule 53 (uses Description class)
- ../slots/has_or_had_type
- ../slots/has_or_had_storage_unit
- ../slots/has_or_had_stores_collection
@ -126,7 +125,7 @@ classes:
- specificity_annotation
- standards_applied
- has_or_had_storage_condition
- has_or_had_description # was: storage_description - migrated per Rule 53
- has_or_had_structured_description # was: storage_description - migrated per Rule 53 (uses Description class)
- has_or_had_identifier # was: storage_id - migrated per Rule 53
- is_or_was_stored_at # was: storage_location - migrated per Rule 53
- has_or_had_label # was: storage_name - migrated per Rule 53
@ -177,13 +176,11 @@ classes:
description: Cold storage for film and photographic materials
- value: ART_STORAGE
description: Climate-controlled art storage
has_or_had_description: # was: storage_description - migrated per Rule 53
has_or_had_structured_description: # was: storage_description - migrated per Rule 53 (uses Description class)
description: |
Description of this storage facility.
MIGRATED from storage_description per slot_fixes.yaml (Rule 53).
Uses Description class with text and language support.
range: Description
inlined: true
multivalued: true
examples:
- value: |
@ -309,7 +306,7 @@ classes:
label_text: Depot Amersfoort
language: nl
has_or_had_type: ART_STORAGE
has_or_had_description:
has_or_had_structured_description:
- description_text: 'Off-site storage depot for Rijksmuseum overflow collections. Climate-controlled facility housing paintings, sculptures, and decorative arts not currently on display.'
description_type: storage
language: en
@ -331,7 +328,7 @@ classes:
label_text: Depot B - Cold Storage
language: en
has_or_had_type: COLD_STORAGE
has_or_had_description:
has_or_had_structured_description:
- description_text: 'Refrigerated vault for film negatives, photographic materials, and temperature-sensitive documents. Maintained at 4°C, 35% RH.'
description_type: storage
language: en

View file

@ -40,8 +40,7 @@ imports:
- ../slots/stores_or_stored # was: stores_object - migrated per Rule 53 (2026-01-15); range now HeritageObject
- ./HeritageObject # Added 2026-01-15 for stores_or_stored range
- ../slots/template_specificity
- ../slots/has_or_had_description # was: unit_description - migrated per Rule 53
- ./Description
- ../slots/has_or_had_structured_description # was: unit_description - migrated per Rule 53 (uses Description class)
# REMOVED - migrated to has_or_had_identifier (2026-01-14, Rule 53)
# - ../slots/unit_id
# - ../slots/unit_identifier
@ -104,7 +103,7 @@ classes:
- specificity_annotation
- stores_or_stored # was: stores_object - migrated per Rule 53 (2026-01-15)
- template_specificity
- has_or_had_description # was: unit_description - migrated per Rule 53
- has_or_had_structured_description # was: unit_description - migrated per Rule 53 (uses Description class)
# REMOVED - migrated to has_or_had_identifier (2026-01-14, Rule 53)
# - unit_id
# - unit_identifier
@ -136,13 +135,11 @@ classes:
unit_type:
range: StorageUnitTypeEnum
required: true
has_or_had_description: # was: unit_description - migrated per Rule 53
has_or_had_structured_description: # was: unit_description - migrated per Rule 53 (uses Description class)
description: |
Description of this storage unit.
MIGRATED from unit_description per slot_fixes.yaml (Rule 53).
Uses Description class with text and language support.
range: Description
inlined: true
multivalued: true
row_number:
range: string
@ -225,7 +222,7 @@ classes:
unit_identifier: NA-2024-BOX-00145
unit_name: Archive Box 145 - WWII Ministry Records
unit_type: ARCHIVE_BOX
has_or_had_description:
has_or_had_structured_description:
- description_text: 'Acid-free archive box containing Ministry of Defense correspondence from 1940-1945. Handle with care.'
description_type: unit
language: en
@ -242,7 +239,7 @@ classes:
unit_identifier: FF-MAPS-042
unit_name: Flat File Drawer 42 - Netherlands Maps
unit_type: FLAT_FILE_DRAWER
has_or_had_description:
has_or_had_structured_description:
- description_text: 'Flat file drawer containing oversized maps of the Netherlands, 1850-1920. Climate-controlled environment.'
description_type: unit
language: en

View file

@ -17,7 +17,7 @@ imports:
# temp_location_reason → has_or_had_rationale + reason_type (enum)
- ../slots/has_or_had_identifier
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/has_or_had_structured_description
- ../slots/has_or_had_rationale
- ../slots/has_or_had_type
- ../slots/is_active
@ -84,7 +84,7 @@ classes:
# temp_location_* slots REMOVED - migrated to generic slots (Rule 53, 2026-01-15)
- has_or_had_identifier
- has_or_had_label
- has_or_had_description
- has_or_had_structured_description
- has_or_had_rationale
- has_or_had_type
- is_active
@ -124,7 +124,7 @@ classes:
description: Traveling exhibition
- value: Emergency Collection Storage - Watersnood 2024
description: Emergency relocation
has_or_had_description:
has_or_had_structured_description:
range: Description
inlined: true
description: Detailed description of the temporary location.
@ -229,7 +229,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/stedelijk-temp-2020
has_or_had_label:
- Stedelijk Museum Temporary Entrance
has_or_had_description:
has_or_had_structured_description:
- description_text: Temporary entrance during main entrance renovation. Access via garden entrance.
description_type: location
language: en
@ -252,7 +252,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/rijksmuseum-popup-groningen
has_or_had_label:
- Rijksmuseum Pop-up Groningen
has_or_had_description:
has_or_had_structured_description:
- description_text: Summer pop-up exhibition in Groninger Forum featuring highlights from the Golden Age collection.
description_type: location
language: en
@ -272,7 +272,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/emergency-storage-2024
has_or_had_label:
- Emergency Collection Storage - Watersnood 2024
has_or_had_description:
has_or_had_structured_description:
- description_text: Emergency relocation of collection materials following flooding at main depot.
description_type: location
language: en

View file

@ -30,7 +30,7 @@ imports:
- ../slots/temporal_extent
- ../slots/starts_or_started_at_location
- ../slots/ends_or_ended_at_location
- ../slots/has_or_had_description
- ../slots/has_or_had_structured_description
- ../slots/has_or_had_policy
- ../slots/specificity_annotation
- ../slots/template_specificity
@ -64,7 +64,7 @@ classes:
- `starts_or_started_at_location`: Origin location
- `ends_or_ended_at_location`: Destination location
- `has_or_had_policy`: Transfer policy governing the transfer
- `has_or_had_description`: Narrative description
- `has_or_had_structured_description`: Narrative description
**Replaces** (per slot_fixes.yaml):
- `transfer_to_collection_date` (simple date)
@ -86,7 +86,7 @@ classes:
- temporal_extent
- starts_or_started_at_location
- ends_or_ended_at_location
- has_or_had_description
- has_or_had_structured_description
- has_or_had_policy
- specificity_annotation
- template_specificity
@ -110,7 +110,7 @@ classes:
range: Location
required: false
inlined: true
has_or_had_description:
has_or_had_structured_description:
description: |
Narrative description of the transfer event.
range: Description
@ -139,6 +139,6 @@ classes:
location_name: "Old Storage Facility"
ends_or_ended_at_location:
location_name: "New Archive Building"
has_or_had_description:
has_or_had_structured_description:
description_text: "Transfer of historical photographs to new climate-controlled facility"
description: "Collection relocation transfer"

View file

@ -24,7 +24,7 @@ imports:
- ../metadata
- ../slots/policy_name
- ../slots/policy_text
- ../slots/has_or_had_description
- ../slots/has_or_had_structured_description
- ../slots/specificity_annotation
- ../slots/template_specificity
- ./Description
@ -65,7 +65,7 @@ classes:
slots:
- policy_name
- policy_text
- has_or_had_description
- has_or_had_structured_description
- specificity_annotation
- template_specificity
@ -80,7 +80,7 @@ classes:
Full text of the policy.
range: string
required: false
has_or_had_description:
has_or_had_structured_description:
description: |
Summary description of the policy.
range: Description

View file

@ -16,7 +16,7 @@ imports:
- ../slots/is_sdh
- ../slots/raw_subtitle_content
- ../slots/specificity_annotation
- ../slots/has_or_had_format # was: subtitle_format - migrated per Rule 53 (2026-01-15)
- ../slots/has_or_had_format
- ../slots/template_specificity
- ../slots/has_or_had_identifier # MIGRATED: was ../slots/track_id (2026-01-14)
- ./TrackIdentifier # Added for has_or_had_identifier migration
@ -241,7 +241,7 @@ classes:
- is_sdh
- raw_subtitle_content
- specificity_annotation
- has_or_had_format # was: subtitle_format - migrated per Rule 53 (2026-01-15)
- has_or_had_format
- template_specificity
- has_or_had_identifier # MIGRATED: was track_id (2026-01-14)
- has_or_had_label # was: track_name
@ -250,10 +250,10 @@ classes:
required: true
includes_timestamp:
ifabsent: 'true'
has_or_had_format: # was: subtitle_format - migrated per Rule 53 (2026-01-15)
has_or_had_format:
description: |
The subtitle format for this video subtitle track.
Migrated from subtitle_format to align with RiC-O naming conventions.
Values: SRT, VTT, TTML, SBV, ASS
range: SubtitleFormatEnum
required: true
examples:

View file

@ -16,9 +16,8 @@ imports:
- ../slots/speaker_count
- ../slots/specificity_annotation
- ../slots/template_specificity
# REMOVED 2026-01-14: ../slots/transcript_format - migrated to has_or_had_format with TranscriptFormat
# REMOVED 2026-01-14: ../slots/transcript_format - migrated to has_or_had_transcript_format with TranscriptFormat
- ../slots/has_or_had_format
- ./TranscriptFormat
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../enums/TranscriptFormatEnum
@ -82,7 +81,7 @@ classes:
- speaker_count
- specificity_annotation
- template_specificity
# REMOVED 2026-01-14: transcript_format - migrated to has_or_had_format with TranscriptFormat
# REMOVED 2026-01-14: transcript_format - migrated to has_or_had_format with TranscriptFormatEnum
- has_or_had_format
slot_usage:
full_text:
@ -105,7 +104,7 @@ classes:
'
description: Transcript with speaker labels
# REMOVED 2026-01-14: transcript_format - migrated to has_or_had_format with TranscriptFormat
# REMOVED 2026-01-14: transcript_format - migrated to has_or_had_format with TranscriptFormatEnum
# transcript_format:
# range: TranscriptFormatEnum
# required: false
@ -114,7 +113,7 @@ classes:
# - value: STRUCTURED
# description: Text with speaker labels and paragraph breaks
has_or_had_format:
range: TranscriptFormat
range: TranscriptFormatEnum
required: false
description: The format of the transcript (plain text, structured, timestamped, etc.)
examples:

View file

@ -15,19 +15,18 @@ imports:
- ../slots/specificity_annotation
- ../slots/template_specificity
# Migrated per slot_fixes.yaml (Rule 53) - 2026-01-14
# warehouse_description → has_or_had_description + Description
# warehouse_description → has_or_had_structured_description + Description
# warehouse_floor_area_sqm → has_or_had_area + Area
# warehouse_id → has_or_had_identifier (uriorcurie range)
# warehouse_managed_by → is_or_was_managed_by + Group
# warehouse_name → has_or_had_label
# warehouse_security_level → has_or_had_security_level + SecurityLevel
- ../slots/has_or_had_description
- ../slots/has_or_had_structured_description # was: warehouse_description - uses Description class
- ../slots/has_or_had_area
- ../slots/has_or_had_identifier
- ../slots/is_or_was_managed_by
- ../slots/has_or_had_label
- ../slots/has_or_had_security_level
- ./Description
- ./Area
- ./Group
- ./SecurityLevel
@ -92,7 +91,7 @@ classes:
- specificity_annotation
- template_specificity
# Migrated per slot_fixes.yaml (Rule 53) - 2026-01-14
- has_or_had_description # was: warehouse_description
- has_or_had_structured_description # was: warehouse_description (uses Description class)
- has_or_had_area # was: warehouse_floor_area_sqm
- has_or_had_identifier # was: warehouse_id
- is_or_was_managed_by # was: warehouse_managed_by
@ -124,12 +123,10 @@ classes:
description: Museum logistics facility
- value: KB Operations Warehouse Leiden
description: Library operations warehouse
has_or_had_description: # was: warehouse_description
has_or_had_structured_description: # was: warehouse_description (uses Description class)
description: |
Description of warehouse purpose and contents.
MIGRATED from warehouse_description per slot_fixes.yaml (Rule 53).
range: Description
inlined: true
examples:
- value:
description_text: Logistics warehouse for exhibition equipment, packing materials, and furniture. Facilities team access only.
@ -241,7 +238,7 @@ classes:
- value:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/rm-logistics-warehouse # was: warehouse_id
has_or_had_label: Rijksmuseum Logistics Warehouse # was: warehouse_name
has_or_had_description: # was: warehouse_description
has_or_had_structured_description: # was: warehouse_description
description_text: Logistics warehouse for exhibition equipment and packing materials. Used by exhibition services team.
description_type: warehouse
has_or_had_type: EXHIBITION_EQUIPMENT
@ -265,7 +262,7 @@ classes:
- value:
has_or_had_identifier: https://nde.nl/ontology/hc/aux/na-supplies-warehouse # was: warehouse_id
has_or_had_label: Nationaal Archief Supplies Warehouse # was: warehouse_name
has_or_had_description: # was: warehouse_description
has_or_had_structured_description: # was: warehouse_description
description_text: General supplies warehouse for archival boxes, office furniture, and operational materials.
description_type: warehouse
has_or_had_type: GENERAL_SUPPLIES

View file

@ -21,7 +21,7 @@ imports:
- ../slots/metadata_standard
- ../slots/sparql_endpoint
- ../slots/oai_pmh_endpoint
- ../slots/identifier
- ../slots/external_identifier
- ../slots/has_or_had_portal_data_source
- ../slots/operated_by
- ../slots/has_or_had_exposed_collection
@ -143,7 +143,7 @@ classes:
- has_or_had_data_service_endpoint
- has_or_had_exposed_collection
- geographic_scope
- identifier
- external_identifier
- implements_auxiliary_platform
- implements_digital_platform
- launch_date
@ -327,7 +327,7 @@ classes:
description: 'Archieven.nl: 80+ archives'
- value: 4000
description: 'Europeana: 4000+ institutions'
identifier:
external_identifier:
range: uriorcurie
multivalued: true
inlined_as_list: true
@ -496,7 +496,7 @@ classes:
portal_status: ACTIVE
record_count: 50000000
participating_institutions: 4000
identifier:
external_identifier:
- http://www.wikidata.org/entity/Q209441
data_license_policy:
- policy_id: https://nde.nl/ontology/hc/policy/europeana-data-exchange

View file

@ -0,0 +1,64 @@
# has_or_had_entity_status - Entity operational status slot
#
# Following RiC-O style naming convention (Rule 39):
# - has_or_had_* indicates temporal relationship
#
# Created to resolve OWL ambiguous type warning on legal_status slot.
# This slot is for LegalStatus objects (ACTIVE, DISSOLVED, etc.),
# distinct from legal_status slot which links to CustodianLegalStatus.
id: https://nde.nl/ontology/hc/slot/has_or_had_entity_status
name: has_or_had_entity_status_slot
title: Has Or Had Entity Status Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
gleif_base: https://www.gleif.org/ontology/Base/
schema: http://schema.org/
imports:
- linkml:types
- ../classes/RegistrationInfo # Contains LegalStatus class
default_prefix: hc
slots:
has_or_had_entity_status:
slot_uri: hc:hasOrHadEntityStatus
range: LegalStatus
description: |
Current or past operational status of a legal entity.
Links to LegalStatus with:
- status_code: ACTIVE, DISSOLVED, MERGED, SUSPENDED, etc.
- status_name: Human-readable status name
**ONTOLOGY ALIGNMENT**:
| Ontology | Property | Notes |
|----------|----------|-------|
| **GLEIF** | `gleif_base:hasEntityStatus` | Close - entity lifecycle status |
| **Schema.org** | `schema:status` | Related - general status |
**DISTINCTION FROM legal_status SLOT**:
| Slot | Range | Purpose |
|------|-------|---------|
| `legal_status` | `CustodianLegalStatus` | Links to legal entity object |
| `has_or_had_entity_status` | `LegalStatus` | Indicates operational status (ACTIVE/DISSOLVED) |
required: true
close_mappings:
- gleif_base:hasEntityStatus
related_mappings:
- schema:status
examples:
- value:
status_code: ACTIVE
status_name: Active
description: Currently operating entity
- value:
status_code: DISSOLVED
status_name: Dissolved
description: Legally dissolved entity

View file

@ -2,7 +2,8 @@
#
# Created per slot_fixes.yaml migration for: typical_response_formats, transcript_format
# Creation date: 2026-01-14
# Rule compliance: 39 (RiC-O naming), 50 (ontology mapping)
# Updated: 2026-01-16 - Broadened range to uriorcurie per Rule 54
# Rule compliance: 39 (RiC-O naming), 50 (ontology mapping), 54 (broaden range)
id: https://nde.nl/ontology/hc/slot/has_or_had_format
name: has_or_had_format
@ -16,7 +17,6 @@ prefixes:
default_prefix: hc
imports:
- linkml:types
@ -32,19 +32,21 @@ slots:
- File formats for documents (PDF, DOCX, TXT)
- Media formats (JPEG, MP3, MP4)
- Transcript formats (VTT, SRT, plain text)
- Subtitle formats (WebVTT, SRT, etc.)
**ONTOLOGY ALIGNMENT**:
- **Primary** (`slot_uri`): `hc:hasOrHadFormat` - Heritage Custodian ObjectProperty
for class-valued format ranges
- **Close**: `dct:format` - Dublin Core format (DatatypeProperty)
- **Primary** (`slot_uri`): `hc:hasOrHadFormat` - Heritage Custodian property
- **Close**: `dct:format` - Dublin Core format
- **Close**: `schema:encodingFormat` - Schema.org encoding format
**Note**: slot_uri changed from dct:format to hc:hasOrHadFormat (2026-01-16)
to allow class-valued ranges (SubtitleFormatEnum, TranscriptFormat).
**Range**: `uriorcurie` (Rule 54)
Broadened range to accept URI/CURIE references to format specifications.
This allows linking to IANA media types, format registries, or internal
format classes while resolving OWL ambiguous type warnings.
**Range**: `Any` (2026-01-16) - Allows string values and class instances.
Classes can narrow to specific format enums/classes via slot_usage.
range: string
range: uriorcurie
multivalued: true
close_mappings:
@ -52,13 +54,21 @@ slots:
- schema:encodingFormat
examples:
- value: "application/json"
description: JSON MIME type for API responses
- value: "text/vtt"
description: WebVTT subtitle/transcript format
- value: "image/jpeg"
description: JPEG image format
- value: "iana:application/json"
description: JSON MIME type for API responses (CURIE)
- value: "iana:text/vtt"
description: WebVTT subtitle/transcript format (CURIE)
- value: "hc:TranscriptFormat/STRUCTURED"
description: Structured transcript with speaker labels (internal CURIE)
- value: "https://www.iana.org/assignments/media-types/image/jpeg"
description: JPEG image format (full URI)
annotations:
custodian_types: '["*"]'
custodian_types_rationale: "Format specifications applicable to all custodian types."
range_broadening_date: "2026-01-16"
range_broadening_rationale: |
Changed from range:string to range:uriorcurie per Rule 54.
This allows linking to IANA media types, format registries, or format classes
while resolving OWL ambiguous type warnings. Replaces need for bespoke slots
like has_or_had_transcript_format or has_or_had_subtitle_format.

View file

@ -50,9 +50,13 @@ slots:
to allow consistent class-valued ranges when classes override. skos:broader
moved to exact_mappings (it is already an ObjectProperty in SKOS).
**Range**: `Any` (2026-01-16) - Allows uriorcurie values and class instances.
**Range**: `uriorcurie` (2026-01-16) - Allows both URIs and CURIE references.
range: string
Note: Individual Type classes may override to their specific type in slot_usage,
but since they're all referring to URIs, this causes no OWL ambiguity when
the base range is uriorcurie (compatible with ObjectProperty).
range: uriorcurie
required: false
multivalued: false

View file

@ -53,9 +53,13 @@ slots:
to allow consistent class-valued ranges when classes override. skos:narrower
moved to exact_mappings (it is already an ObjectProperty in SKOS).
**Range**: `Any` (2026-01-16) - Allows uriorcurie values and class instances.
**Range**: `uriorcurie` (2026-01-16) - Allows both URIs and CURIE references.
range: string
Note: Individual Type classes may override to their specific type in slot_usage,
but since they're all referring to URIs, this causes no OWL ambiguity when
the base range is uriorcurie (compatible with ObjectProperty).
range: uriorcurie
required: false
multivalued: true
inlined_as_list: true

View file

@ -51,7 +51,7 @@ slots:
**Range**: `Any` (2026-01-16) - Allows both string values and Label class instances.
range: string
range: uriorcurie
required: false
multivalued: true

View file

@ -0,0 +1,67 @@
# has_or_had_observation_source_document - Source document for observation
#
# Following RiC-O style naming convention (Rule 39):
# - has_or_had_* indicates temporal relationship
#
# Created to resolve OWL ambiguous type warning on observation_source slot.
# This slot is for SourceDocument objects (structured source references),
# distinct from observation_source slot which uses string values.
id: https://nde.nl/ontology/hc/slot/has_or_had_observation_source_document
name: has_or_had_observation_source_document_slot
title: Has Or Had Observation Source Document Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
prov: http://www.w3.org/ns/prov#
dcterms: http://purl.org/dc/terms/
imports:
- linkml:types
- ../classes/SourceDocument
default_prefix: hc
slots:
has_or_had_observation_source_document:
slot_uri: hc:hasOrHadObservationSourceDocument
range: SourceDocument
description: |
Structured source document where this observation was found.
Links to SourceDocument with:
- source_type: "Staff directory", "Annual report", etc.
- source_uri: URL if available
- observation_date: When source was consulted
**PiCo Pattern**: PersonObservation MUST link to source (evidence-based)
**PROV-O**: `prov:hadPrimarySource` for provenance tracking
**Source Types**:
- Staff directory (online or print)
- Organizational chart
- Annual report
- Institutional website
- Archival personnel records
- Publication credits
- Email signature
**DISTINCTION FROM observation_source SLOT**:
| Slot | Range | Purpose |
|------|-------|---------|
| `observation_source` | `string` | Simple text reference to source |
| `has_or_had_observation_source_document` | `SourceDocument` | Structured source with metadata |
required: false
close_mappings:
- prov:hadPrimarySource
related_mappings:
- dcterms:source
examples:
- value:
source_type: Staff directory
source_uri: https://example.org/staff
observation_date: "2025-01-10"
description: Staff directory source with structured metadata

View file

@ -40,7 +40,7 @@ slots:
**Note**: slot_uri changed from skos:note to hc:hasOrHadRationale (2026-01-16)
to allow class-valued ranges when classes use Rationale class.
range: string
range: uriorcurie
close_mappings:
- skos:note

View file

@ -23,7 +23,7 @@ default_prefix: hc
slots:
has_or_had_status:
slot_uri: hc:hasOrHadStatus
range: string
range: uriorcurie
description: |
Current or past status of an entity.

View file

@ -0,0 +1,62 @@
# has_or_had_structured_description slot
# Slot for structured Description class instances
#
# Following RiC-O naming convention (Rule 39): "hasOrHad..." pattern
# for temporal relationships in heritage domain.
#
# Created to resolve OWL ambiguous type warning on has_or_had_description slot.
# This slot is for Description class (structured descriptions with language/type),
# distinct from has_or_had_description slot which uses string values.
#
# Generation date: 2026-01-16
# Rule compliance: 38 (slot centralization + semantic URI), 39 (RiC-O naming), 42 (no prefix)
id: https://nde.nl/ontology/hc/slot/has_or_had_structured_description
name: has_or_had_structured_description_slot
title: Has Or Had Structured Description Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
dcterms: http://purl.org/dc/terms/
skos: http://www.w3.org/2004/02/skos/core#
default_prefix: hc
imports:
- linkml:types
- ../classes/Description
slots:
has_or_had_structured_description:
slot_uri: hc:hasOrHadStructuredDescription
range: Description
description: |
Structured description with language, type, and provenance metadata.
**DISTINCTION FROM has_or_had_description SLOT**:
| Slot | Range | Purpose |
|------|-------|---------|
| `has_or_had_description` | `string` | Simple text description |
| `has_or_had_structured_description` | `Description` | Typed description with metadata |
**Temporal Semantics** (RiC-O Pattern):
The "hasOrHad" naming follows RiC-O convention indicating this relationship
may be historical - an entity's description may change over time.
**Ontological Alignment**:
- **Primary** (`slot_uri`): `hc:hasOrHadStructuredDescription` - ObjectProperty
- **Close**: `dcterms:description` - Dublin Core (DatatypeProperty)
- **Close**: `skos:definition` - SKOS definition
required: false
inlined: true
close_mappings:
- dcterms:description
- skos:definition
examples:
- value:
description_text: "A historic reading room with original 19th century furnishings"
description_type: FACILITY
description_language: en
description: Structured facility description with language tag

View file

@ -5,7 +5,8 @@
# for temporal relationships in heritage domain.
#
# Generation date: 2026-01-13
# Rule compliance: 38 (slot centralization + semantic URI), 39 (RiC-O naming), 42 (no prefix)
# Updated: 2026-01-16 - Broadened range to uriorcurie per Rule 54
# Rule compliance: 38, 39, 42, 53, 54 (broaden range, not bespoke predicates)
id: https://nde.nl/ontology/hc/slot/has_or_had_type
name: has_or_had_type_slot
@ -35,29 +36,25 @@ slots:
may be historical - an entity may have been reclassified over time.
**Ontological Alignment**:
- **Primary** (`slot_uri`): `hc:hasOrHadType` - Heritage Custodian ObjectProperty
allowing class-valued ranges for type hierarchies
- **Primary** (`slot_uri`): `hc:hasOrHadType` - Heritage Custodian property
- **Exact**: `crm:P2_has_type` - CIDOC-CRM predicate for typing entities
(range: E55_Type, an ObjectProperty)
- **Close**: `dcterms:type` - Dublin Core type predicate
- **Related**: `schema:additionalType` - Schema.org for web semantics
**Usage**:
This is a GENERIC slot intended for reuse across multiple classes.
Classes should specialize the range in slot_usage to reference the
appropriate Type class hierarchy (e.g., StorageType, ZoneType, etc.).
Classes may narrow the range in slot_usage to reference specific Type class
hierarchies (e.g., StorageType, ZoneType, etc.).
**Range**: `uriorcurie` (Rule 54)
Broadened range to accept URI/CURIE references to type concepts.
This resolves OWL "Ambiguous type" warnings while maintaining semantic richness.
Classes can still narrow to specific Type classes via slot_usage.
**Cardinality**:
Multivalued - entities may have multiple type classifications.
**Note**: slot_uri changed from crm:P2_has_type to hc:hasOrHadType (2026-01-16)
to resolve OWL ambiguous type warning when classes override range to class types.
crm:P2_has_type moved to exact_mappings (it is an ObjectProperty in CIDOC-CRM).
**Range**: `Any` (2026-01-16) - Allows both string values and class instances.
Classes narrow this to specific Type class hierarchies via slot_usage.
range: string
range: uriorcurie
required: false
multivalued: true
inlined_as_list: true
@ -86,20 +83,27 @@ slots:
zone_type, warehouse_type, unit_type, treatment_type, storage_type,
statement_type, sub_guide_type, wikidata_mapping_type
migration_date: "2026-01-13"
range_broadening_date: "2026-01-16"
range_broadening_rationale: |
Changed from range:string to range:uriorcurie per Rule 54.
This resolves OWL "Ambiguous type" warning while maintaining
semantic flexibility. Classes can narrow to specific Type classes
via slot_usage without causing DatatypeProperty/ObjectProperty ambiguity.
predicate_clarification: |
slot_uri references a PREDICATE (crm:P2_has_type), not a class.
The range should be specialized per class to reference appropriate Type classes.
slot_uri references a PREDICATE (hc:hasOrHadType), not a class.
comments:
- "Generic type slot for reuse across multiple classes"
- "Specialize range in slot_usage for specific Type class hierarchies"
- "slot_uri=crm:P2_has_type is a PREDICATE, not a class"
- "Range: uriorcurie - accepts URI/CURIE references to type concepts"
- "slot_uri=hc:hasOrHadType is a PREDICATE, not a class"
- "RiC-O naming: hasOrHad indicates potentially historical relationship"
- "Multivalued: entities may have multiple type classifications"
- "Range: Any - resolves OWL ambiguous type warning (2026-01-16)"
- "Rule 54: Broadened range instead of creating bespoke predicates"
examples:
- value: StorageType:ARCHIVE_DEPOT
description: "Storage typed as archive depot"
- value: ZoneType:CLIMATE_CONTROLLED
description: "Environmental zone type"
- value: "hc:StorageType/ARCHIVE_DEPOT"
description: "Storage typed as archive depot (CURIE reference)"
- value: "hc:ZoneType/CLIMATE_CONTROLLED"
description: "Environmental zone type (CURIE reference)"
- value: "https://example.org/vocab/historic-building"
description: "External vocabulary reference (full URI)"

View file

@ -58,7 +58,7 @@ slots:
**Range**: `Any` (2026-01-16) - Allows uri/string values and URL class instances.
range: URL
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
required: false
multivalued: true
inlined: true

View file

@ -37,7 +37,7 @@ slots:
**Range**: `Any` (2026-01-16) - Allows uriorcurie values and class instances.
range: uriorcurie
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
multivalued: true
exact_mappings:

View file

@ -37,7 +37,7 @@ slots:
to resolve OWL ambiguous type warning when classes override range
to class types (e.g., CustodianObservation).
range: uriorcurie
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
exact_mappings:
- prov:wasDerivedFrom

View file

@ -55,7 +55,7 @@ slots:
**Cardinality**:
Multivalued - an entity may have equivalences in multiple systems.
range: string
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
required: false
multivalued: true
inlined_as_list: true

View file

@ -37,7 +37,7 @@ slots:
to resolve OWL ambiguous type warning when classes override range
to class types (e.g., ReconstructionActivity).
range: uriorcurie
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
exact_mappings:
- prov:wasGeneratedBy

View file

@ -60,7 +60,7 @@ slots:
**Cardinality**:
Multivalued - entities may have multiple classifications.
range: string
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
required: false
multivalued: true
inlined_as_list: true

View file

@ -62,7 +62,7 @@ slots:
**Cardinality**:
Multivalued - an entity may have multiple associations.
range: string
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
required: false
multivalued: true
inlined_as_list: true

View file

@ -5669,4 +5669,214 @@ fixes:
using Description class with description_type: from_owner. Migrated for symmetry
with to_owner_text which was migrated earlier in same session. Owner class not
used (existing from_owner slot provides structured reference). Original slot
archived to archive/from_owner_text_archived_20260115.yaml.'
archived to archive/from_owner_text_archived_20260115.yaml.'
- original_slot_id: https://nde.nl/ontology/hc/slot/about_text
revision:
- label: has_or_had_description
type: slot
- label: Description
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/address_type
revision:
- label: has_or_had_address
type: slot
- label: Address
type: class
- label: has_or_had_type
type: slot
- label: AddressType
type: class
- label: includes_or_included
type: slot
- label: AddressTypes
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/algorithm_name
revision:
- label: has_or_had_label
type: slot
- label: Label
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/algorithm_version
revision:
- label: has_or_had_version
type: slot
- label: Version
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/amount
revision:
- label: has_or_had_quantity
type: slot
- label: Quantity
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/applies_or_applied_to_call
revision:
- label: applies_or_applied_to
type: slot
- label: CallForApplication
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/approximation_level
revision:
- label: has_or_had_level
type: slot
- label: ApproximationLevel
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/archival_reference
revision:
- label: has_or_had_provenance
type: slot
- label: Provenance
type: class
- label: has_or_had_reference
type: slot
- label: Reference
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/area_value
revision:
- label: has_or_had_area
type: slot
- label: Area
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/arrangement_level
revision:
- label: has_or_had_level
type: slot
- label: ArrangementLevel
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/asserter_contact
revision:
- label: has_or_had_contact_person
type: slot
- label: ContactPerson
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/asserter_type
revision:
- label: has_or_had_type
type: slot
- label: AsserterType
type: class
- label: includes_or_included
type: slot
- label: AsserterTypes
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/asserter_version
revision:
- label: has_or_had_version
type: slot
- label: Version
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/assessment_date
revision:
- label: is_or_was_assessed
type: slot
- label: Assessment
type: class
- label: temporal_extent
type: slot
- label: TimeSpan
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audience_size
revision:
- label: serves_or_served
type: slot
- label: UserCommunity
type: class
- label: has_or_had_quantity
type: slot
- label: AudienceSize
type: class
- label: has_or_had_unit
type: slot
- label: MeasurementUnit
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audience_type
revision:
- label: serves_or_served
type: slot
- label: UserCommunity
type: class
- label: has_or_had_type
type: slot
- label: UserCommunityType
type: class
- label: includes_or_included
type: slot
- label: UserCommunityTypes
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audio_quality_score
revision:
- label: has_or_had_audio
type: slot
- label: Audio
type: class
- label: has_or_had_score
type: slot
- label: QualityScore
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audit_date
revision:
- label: is_or_was_audited
type: slot
- label: AuditEvent
type: class
- label: temporal_extent
type: slot
- label: TimeSpan
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audit_opinion
revision:
- label: is_or_was_audited
type: slot
- label: AuditEvent
type: class
- label: concludes_or_concluded
type: slot
- label: AuditOpinion
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audit_status
revision:
- label: is_or_was_audited
type: slot
- label: AuditEvent
type: class
- label: has_or_had_status
type: slot
- label: AuditStatus
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/auditor_name
revision:
- label: is_or_was_audited
type: slot
- label: AuditEvent
type: class
- label: is_or_was_conducted_by
type: slot
- label: Auditor
type: class
- label: has_or_had_name
type: slot
- label: Name
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/author_affiliation
revision:
- label: is_or_was_affiliated_with
type: slot
- label: Affiliation
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/author_identifier
revision:
- label: has_or_had_identifier
type: slot
- label: Identifier
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/author_name
revision:
- label: has_or_had_name
type: slot
- label: Name
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/author_role
revision:
- label: has_or_had_role
type: slot
- label: AuthorRole
type: class

View file

@ -0,0 +1,40 @@
#!/bin/bash
# gen-heritage-owl.sh - Generate OWL ontology from Heritage Custodian LinkML schema
#
# Usage:
# ./scripts/gen-heritage-owl.sh [output-file] [additional-args...]
#
# Examples:
# ./scripts/gen-heritage-owl.sh # Output to stdout
# ./scripts/gen-heritage-owl.sh heritage_custodian.owl # Output to file
# ./scripts/gen-heritage-owl.sh -f ttl # Turtle format
#
# Why --type-objects is required:
# The Heritage Custodian schema uses generic slots (e.g., has_or_had_type,
# has_or_had_format) with `range: uriorcurie` that are narrowed by classes
# via slot_usage. While the range broadening to uriorcurie resolves most
# OWL ambiguity warnings, using --type-objects ensures consistent
# ObjectProperty treatment for all polymorphic slots.
#
# See also:
# - Rule 55: Broaden Generic Predicate Ranges (.opencode/rules/broaden-generic-predicate-ranges-rule.md)
# - Rule 53: Full Slot Migration (slot_fixes.yaml)
#
# Created: 2026-01-16
# Updated: 2026-01-16
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCHEMA_DIR="$(dirname "$SCRIPT_DIR")"
SCHEMA_FILE="${SCHEMA_DIR}/01_custodian_name_modular.yaml"
if [[ ! -f "$SCHEMA_FILE" ]]; then
echo "Error: Schema file not found: $SCHEMA_FILE" >&2
exit 1
fi
# Run gen-owl with --type-objects flag
# This treats types as objects (ObjectProperty) rather than literals (DatatypeProperty)
# which matches our polymorphic slot design pattern
exec gen-owl --type-objects "$SCHEMA_FILE" "$@"

View file

@ -381,6 +381,19 @@
color: #f59e0b;
}
.stat-card.info .stat-value {
color: #3b82f6;
}
.stat-card.info.active {
border-color: #3b82f6;
background: rgba(59, 130, 246, 0.1);
}
.dark .stat-card.info.active {
background: rgba(59, 130, 246, 0.15);
}
.stat-card.progress {
position: relative;
}
@ -2121,3 +2134,118 @@
background: rgba(239, 68, 68, 0.15);
color: #f87171;
}
/* WCMS-Only Profiles Styles */
.wcms-only-search {
position: relative;
padding: 0.75rem;
border-bottom: 1px solid var(--border-color, #e0e0e0);
}
.wcms-only-search .search-input {
width: 100%;
padding: 0.5rem 2rem 0.5rem 0.75rem;
border: 1px solid var(--border-color, #e0e0e0);
border-radius: 6px;
font-size: 0.875rem;
background: var(--bg-primary, #fff);
color: var(--text-primary, #1a1a1a);
}
.wcms-only-search .search-input:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
.wcms-only-search .clear-search {
position: absolute;
right: 1rem;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: var(--text-secondary, #666);
cursor: pointer;
padding: 0.25rem;
display: flex;
align-items: center;
justify-content: center;
}
.wcms-only-search .clear-search:hover {
color: var(--text-primary, #1a1a1a);
}
.wcms-only-list .profile-item {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.75rem 1rem;
}
.profile-item-actions {
display: flex;
gap: 0.5rem;
margin-top: 0.25rem;
}
.linkedin-search-btn {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.35rem 0.75rem;
background: linear-gradient(135deg, #0077b5 0%, #005885 100%);
color: white;
border: none;
border-radius: 4px;
font-size: 0.75rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.linkedin-search-btn:hover {
background: linear-gradient(135deg, #005885 0%, #004266 100%);
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 119, 181, 0.3);
}
.status-badge {
font-size: 0.65rem;
padding: 0.15rem 0.4rem;
border-radius: 3px;
font-weight: 500;
text-transform: uppercase;
}
.status-badge.active {
background: rgba(34, 197, 94, 0.15);
color: #16a34a;
}
.status-badge.blocked {
background: rgba(239, 68, 68, 0.15);
color: #dc2626;
}
.dark .status-badge.active {
background: rgba(34, 197, 94, 0.2);
color: #4ade80;
}
.dark .status-badge.blocked {
background: rgba(239, 68, 68, 0.2);
color: #f87171;
}
.date-badge {
font-size: 0.7rem;
color: var(--text-secondary, #666);
}
.pagination-info {
font-size: 0.8rem;
color: var(--text-secondary, #666);
padding: 0 0.5rem;
}

View file

@ -585,6 +585,38 @@ export default function EntityReviewPage() {
}
}, [fetchProfiles, fetchStats, fetchSignalTypes, isAuthenticated]);
// Fetch WCMS-only profiles when that filter is selected
useEffect(() => {
if (!isAuthenticated || statsFilter !== 'wcms_only') return;
const fetchWcmsOnlyProfiles = async () => {
setWcmsOnlyLoading(true);
try {
const params = new URLSearchParams({
page: wcmsOnlyPage.toString(),
page_size: '50',
});
if (wcmsOnlySearch.trim()) {
params.append('search', wcmsOnlySearch.trim());
}
const response = await fetch(`${API_BASE}/api/review/wcms-only?${params}`);
if (!response.ok) throw new Error('Failed to fetch WCMS-only profiles');
const data = await response.json();
setWcmsOnlyProfiles(data.profiles || []);
setWcmsOnlyTotal(data.total || 0);
} catch (err) {
console.error('Failed to fetch WCMS-only profiles:', err);
setWcmsOnlyProfiles([]);
setWcmsOnlyTotal(0);
} finally {
setWcmsOnlyLoading(false);
}
};
fetchWcmsOnlyProfiles();
}, [isAuthenticated, statsFilter, wcmsOnlyPage, wcmsOnlySearch]);
// Keyboard shortcuts
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
@ -814,6 +846,15 @@ export default function EntityReviewPage() {
<span className="stat-label">In afwachting</span>
</div>
</Tooltip>
<Tooltip content={language === 'nl' ? 'WCMS profielen zonder LinkedIn kandidaten - klaar voor zoeken' : 'WCMS profiles without LinkedIn candidates - ready for search'} position="bottom">
<div
className={`stat-card info clickable ${statsFilter === 'wcms_only' ? 'active' : ''}`}
onClick={() => { setStatsFilter('wcms_only'); setWcmsOnlyPage(1); }}
>
<span className="stat-value">{(stats.wcms_only_count || 0).toLocaleString()}</span>
<span className="stat-label">Zoek LinkedIn</span>
</div>
</Tooltip>
{stats.likely_wrong_person !== undefined && stats.likely_wrong_person > 0 && (
<Tooltip content={t('wrongPersonWarning')} position="bottom">
<div className="stat-card danger">
@ -1165,6 +1206,147 @@ export default function EntityReviewPage() {
<Search size={32} />
<span>{language === 'nl' ? 'Geen resultaten gevonden' : 'No results found'}</span>
</div>
) : statsFilter === 'wcms_only' ? (
/* WCMS-Only Profiles View */
<>
{/* Search Input for WCMS-only */}
<div className="wcms-only-search">
<input
type="text"
placeholder={language === 'nl' ? 'Zoek op naam of email...' : 'Search by name or email...'}
value={wcmsOnlySearch}
onChange={(e) => {
setWcmsOnlySearch(e.target.value);
setWcmsOnlyPage(1);
}}
className="search-input"
/>
{wcmsOnlySearch && (
<button
className="clear-search"
onClick={() => {
setWcmsOnlySearch('');
setWcmsOnlyPage(1);
}}
title={language === 'nl' ? 'Wissen' : 'Clear'}
>
<X size={14} />
</button>
)}
</div>
{/* Results count */}
{!wcmsOnlyLoading && wcmsOnlyTotal > 0 && (
<div className="search-stats">
<span>{wcmsOnlyTotal.toLocaleString()} {language === 'nl' ? 'profielen zonder LinkedIn' : 'profiles without LinkedIn'}</span>
</div>
)}
{wcmsOnlyLoading ? (
<div className="loading-state">
<Loader2 className="animate-spin" size={24} />
<span>{language === 'nl' ? 'Laden...' : 'Loading...'}</span>
</div>
) : wcmsOnlyProfiles.length === 0 ? (
<div className="empty-state">
<Database size={32} />
<span>{language === 'nl' ? 'Geen profielen gevonden' : 'No profiles found'}</span>
</div>
) : (
<>
<ul className="profile-list wcms-only-list">
{wcmsOnlyProfiles.map((profile, idx) => (
<li
key={profile.user_id || profile.email || `wcms-only-${idx}`}
className="profile-item wcms-only-item"
>
<div className="profile-item-header">
<User size={16} />
<span className="profile-name">{profile.name || profile.username || 'Unknown'}</span>
{profile.status && (
<span className={`status-badge ${profile.status.toLowerCase()}`}>
{profile.status}
</span>
)}
</div>
<div className="profile-item-meta">
{profile.email && (
<span className="email-badge" title={profile.email}>
<Mail size={12} />
{profile.email}
</span>
)}
{profile.abs_id && (
<span className="wcms-id-badge" title={`ABS ID: ${profile.abs_id}`}>
ID: {profile.abs_id}
</span>
)}
{profile.registered_since && (
<span className="date-badge" title={`Registered: ${profile.registered_since}`}>
{profile.registered_since}
</span>
)}
</div>
<div className="profile-item-actions">
<button
className="linkedin-search-btn"
onClick={() => {
const searchQuery = encodeURIComponent(profile.name || profile.username || profile.email || '');
window.open(`https://www.linkedin.com/search/results/all/?keywords=${searchQuery}`, '_blank');
}}
title={language === 'nl' ? 'Zoek op LinkedIn' : 'Search on LinkedIn'}
>
<Search size={14} />
<span>LinkedIn</span>
</button>
</div>
</li>
))}
</ul>
{/* Pagination for WCMS-only */}
<div className="pagination">
<button
onClick={() => setWcmsOnlyPage(1)}
disabled={wcmsOnlyPage === 1}
title="First page"
className="pagination-btn"
>
<ChevronLeft size={14} />
<ChevronLeft size={14} style={{ marginLeft: -8 }} />
</button>
<button
onClick={() => setWcmsOnlyPage(p => Math.max(1, p - 1))}
disabled={wcmsOnlyPage === 1}
title="Previous page"
className="pagination-btn"
>
<ChevronLeft size={16} />
</button>
<span className="pagination-info">
{wcmsOnlyPage} / {Math.ceil(wcmsOnlyTotal / 50)}
</span>
<button
onClick={() => setWcmsOnlyPage(p => Math.min(Math.ceil(wcmsOnlyTotal / 50), p + 1))}
disabled={wcmsOnlyPage >= Math.ceil(wcmsOnlyTotal / 50)}
title="Next page"
className="pagination-btn"
>
<ChevronRight size={16} />
</button>
<button
onClick={() => setWcmsOnlyPage(Math.ceil(wcmsOnlyTotal / 50))}
disabled={wcmsOnlyPage >= Math.ceil(wcmsOnlyTotal / 50)}
title="Last page"
className="pagination-btn"
>
<ChevronRight size={14} />
<ChevronRight size={14} style={{ marginLeft: -8 }} />
</button>
</div>
</>
)}
</>
) : loading ? (
<div className="loading-state">
<Loader2 className="animate-spin" size={24} />

View file

@ -1,5 +1,5 @@
{
"generated": "2026-01-16T14:04:19.745Z",
"generated": "2026-01-16T14:06:37.301Z",
"schemaRoot": "/schemas/20251121/linkml",
"totalFiles": 3010,
"categoryCounts": {

View file

@ -1,61 +0,0 @@
# TypeClass - Abstract base class for all type classification classes
#
# This class serves as the common ancestor for all *Type classes in the heritage ontology.
# It enables the `any_of` pattern in generic slots like `has_or_had_type` to accept
# both string values and class instances, resolving OWL "Ambiguous type" warnings.
#
# Rule compliance:
# - Rule 53: Enables generic slots via any_of pattern
# - Rule 39: Supports RiC-O temporal naming convention
# - Rule 0b: Part of Type/Types naming convention
#
# Generation date: 2026-01-16
# Purpose: Resolve 18 OWL ambiguous type warnings from gen-owl
id: https://nde.nl/ontology/hc/class/TypeClass
name: type_class
title: Type Class (Abstract Base)
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
skos: http://www.w3.org/2004/02/skos/core#
default_prefix: hc
imports:
- linkml:types
classes:
TypeClass:
class_uri: skos:Concept
abstract: true
description: |
Abstract base class for all type classification classes in the heritage ontology.
**Purpose**:
Enables the `any_of` pattern in generic slots (e.g., `has_or_had_type`) to accept
both string literals and class instances. This resolves OWL "Ambiguous type"
warnings that occur when slots have `range: string` but classes override to
class types via `slot_usage`.
**Inheritance**:
All concrete Type classes (AddressType, BackupType, ConditionType, etc.)
should inherit from this class using `is_a: TypeClass`.
**Ontological Alignment**:
- class_uri: `skos:Concept` - Type classes represent controlled vocabulary concepts
**See Also**:
- Rule 0b: LinkML Type/Types File Naming Convention
- Rule 53: No bespoke slots - generic/reusable patterns
annotations:
specificity_score: 0.10
specificity_rationale: |
Very low specificity - this is a foundational abstract class used as the
base for all type classification classes across the entire ontology.
owl_fix_date: "2026-01-16"
owl_fix_purpose: |
Created to resolve 18 "Ambiguous type" warnings from gen-owl.
Serves as range in any_of patterns for generic slots.

View file

@ -16,7 +16,7 @@ imports:
- ../slots/is_sdh
- ../slots/raw_subtitle_content
- ../slots/specificity_annotation
- ../slots/has_or_had_subtitle_format # was: has_or_had_format - specialized for SubtitleFormatEnum (2026-01-16)
- ../slots/has_or_had_format
- ../slots/template_specificity
- ../slots/has_or_had_identifier # MIGRATED: was ../slots/track_id (2026-01-14)
- ./TrackIdentifier # Added for has_or_had_identifier migration
@ -241,7 +241,7 @@ classes:
- is_sdh
- raw_subtitle_content
- specificity_annotation
- has_or_had_subtitle_format # was: has_or_had_format - specialized for SubtitleFormatEnum (2026-01-16)
- has_or_had_format
- template_specificity
- has_or_had_identifier # MIGRATED: was track_id (2026-01-14)
- has_or_had_label # was: track_name
@ -250,11 +250,11 @@ classes:
required: true
includes_timestamp:
ifabsent: 'true'
has_or_had_subtitle_format: # was: has_or_had_format - specialized for SubtitleFormatEnum (2026-01-16)
has_or_had_format:
description: |
The subtitle format for this video subtitle track.
Migrated from subtitle_format to align with RiC-O naming conventions.
# range: SubtitleFormatEnum - defined in slot, no override needed
Values: SRT, VTT, TTML, SBV, ASS
range: SubtitleFormatEnum
required: true
examples:
- value: VTT

View file

@ -17,7 +17,7 @@ imports:
- ../slots/specificity_annotation
- ../slots/template_specificity
# REMOVED 2026-01-14: ../slots/transcript_format - migrated to has_or_had_transcript_format with TranscriptFormat
- ../slots/has_or_had_transcript_format
- ../slots/has_or_had_format
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../enums/TranscriptFormatEnum
@ -81,8 +81,8 @@ classes:
- speaker_count
- specificity_annotation
- template_specificity
# REMOVED 2026-01-14: transcript_format - migrated to has_or_had_transcript_format with TranscriptFormat
- has_or_had_transcript_format
# REMOVED 2026-01-14: transcript_format - migrated to has_or_had_format with TranscriptFormatEnum
- has_or_had_format
slot_usage:
full_text:
range: string
@ -104,7 +104,7 @@ classes:
'
description: Transcript with speaker labels
# REMOVED 2026-01-14: transcript_format - migrated to has_or_had_transcript_format with TranscriptFormat
# REMOVED 2026-01-14: transcript_format - migrated to has_or_had_format with TranscriptFormatEnum
# transcript_format:
# range: TranscriptFormatEnum
# required: false
@ -112,8 +112,8 @@ classes:
# examples:
# - value: STRUCTURED
# description: Text with speaker labels and paragraph breaks
has_or_had_transcript_format:
# range: TranscriptFormat - defined in slot, no override needed
has_or_had_format:
range: TranscriptFormatEnum
required: false
description: The format of the transcript (plain text, structured, timestamped, etc.)
examples:

View file

@ -2,7 +2,8 @@
#
# Created per slot_fixes.yaml migration for: typical_response_formats, transcript_format
# Creation date: 2026-01-14
# Rule compliance: 39 (RiC-O naming), 50 (ontology mapping)
# Updated: 2026-01-16 - Broadened range to uriorcurie per Rule 54
# Rule compliance: 39 (RiC-O naming), 50 (ontology mapping), 54 (broaden range)
id: https://nde.nl/ontology/hc/slot/has_or_had_format
name: has_or_had_format
@ -16,7 +17,6 @@ prefixes:
default_prefix: hc
imports:
- linkml:types
@ -32,19 +32,21 @@ slots:
- File formats for documents (PDF, DOCX, TXT)
- Media formats (JPEG, MP3, MP4)
- Transcript formats (VTT, SRT, plain text)
- Subtitle formats (WebVTT, SRT, etc.)
**ONTOLOGY ALIGNMENT**:
- **Primary** (`slot_uri`): `hc:hasOrHadFormat` - Heritage Custodian ObjectProperty
for class-valued format ranges
- **Close**: `dct:format` - Dublin Core format (DatatypeProperty)
- **Primary** (`slot_uri`): `hc:hasOrHadFormat` - Heritage Custodian property
- **Close**: `dct:format` - Dublin Core format
- **Close**: `schema:encodingFormat` - Schema.org encoding format
**Note**: slot_uri changed from dct:format to hc:hasOrHadFormat (2026-01-16)
to allow class-valued ranges (SubtitleFormatEnum, TranscriptFormat).
**Range**: `uriorcurie` (Rule 54)
Broadened range to accept URI/CURIE references to format specifications.
This allows linking to IANA media types, format registries, or internal
format classes while resolving OWL ambiguous type warnings.
**Range**: `Any` (2026-01-16) - Allows string values and class instances.
Classes can narrow to specific format enums/classes via slot_usage.
range: string
range: uriorcurie
multivalued: true
close_mappings:
@ -52,13 +54,21 @@ slots:
- schema:encodingFormat
examples:
- value: "application/json"
description: JSON MIME type for API responses
- value: "text/vtt"
description: WebVTT subtitle/transcript format
- value: "image/jpeg"
description: JPEG image format
- value: "iana:application/json"
description: JSON MIME type for API responses (CURIE)
- value: "iana:text/vtt"
description: WebVTT subtitle/transcript format (CURIE)
- value: "hc:TranscriptFormat/STRUCTURED"
description: Structured transcript with speaker labels (internal CURIE)
- value: "https://www.iana.org/assignments/media-types/image/jpeg"
description: JPEG image format (full URI)
annotations:
custodian_types: '["*"]'
custodian_types_rationale: "Format specifications applicable to all custodian types."
range_broadening_date: "2026-01-16"
range_broadening_rationale: |
Changed from range:string to range:uriorcurie per Rule 54.
This allows linking to IANA media types, format registries, or format classes
while resolving OWL ambiguous type warnings. Replaces need for bespoke slots
like has_or_had_transcript_format or has_or_had_subtitle_format.

View file

@ -51,7 +51,7 @@ slots:
**Range**: `Any` (2026-01-16) - Allows both string values and Label class instances.
range: string
range: uriorcurie
required: false
multivalued: true

View file

@ -40,7 +40,7 @@ slots:
**Note**: slot_uri changed from skos:note to hc:hasOrHadRationale (2026-01-16)
to allow class-valued ranges when classes use Rationale class.
range: string
range: uriorcurie
close_mappings:
- skos:note

View file

@ -23,7 +23,7 @@ default_prefix: hc
slots:
has_or_had_status:
slot_uri: hc:hasOrHadStatus
range: string
range: uriorcurie
description: |
Current or past status of an entity.

View file

@ -1,64 +0,0 @@
# has_or_had_subtitle_format - Subtitle format specification slot
#
# Created to fix gen-owl "Ambiguous type for: has_or_had_format" warning.
# The base has_or_had_format slot has range: string, but VideoSubtitle needs
# range: SubtitleFormatEnum. This specialized slot provides the enum-typed range.
#
# Creation date: 2026-01-16
# Rule compliance: 39 (RiC-O naming), 50 (ontology mapping)
id: https://nde.nl/ontology/hc/slot/has_or_had_subtitle_format
name: has_or_had_subtitle_format
title: Has or Had Subtitle Format
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
default_prefix: hc
imports:
- linkml:types
- ../enums/SubtitleFormatEnum
slots:
has_or_had_subtitle_format:
slot_uri: hc:hasOrHadSubtitleFormat
description: |
The subtitle format for video subtitle tracks.
**USAGE**:
Specifies the technical format of a subtitle file (SRT, VTT, TTML, etc.).
This slot is used exclusively by VideoSubtitle and related classes.
**SUBTITLE FORMATS**:
| Format | Extension | Features | Use Case |
|--------|-----------|----------|----------|
| SRT | .srt | Simple, universal | Most video players |
| VTT | .vtt | W3C standard, styling | HTML5 video, web |
| TTML | .ttml/.dfxp | XML, rich styling | Broadcast, streaming |
| SBV | .sbv | YouTube native | YouTube uploads |
| ASS | .ass | Advanced styling | Anime, complex layouts |
**ONTOLOGY ALIGNMENT**:
- **Primary** (`slot_uri`): `hc:hasOrHadSubtitleFormat` - Heritage Custodian property
- **Related**: `schema:encodingFormat` - General encoding format
range: SubtitleFormatEnum
required: false
close_mappings:
- schema:encodingFormat
examples:
- value: VTT
description: WebVTT format (W3C standard for HTML5 video)
- value: SRT
description: SubRip format (most widely supported)
- value: TTML
description: Timed Text Markup Language (broadcast standard)
annotations:
custodian_types: '["*"]'
custodian_types_rationale: "Subtitle formats applicable to all custodian types with video content."

View file

@ -1,64 +0,0 @@
# has_or_had_transcript_format - Transcript format specification slot
#
# Created to fix gen-owl "Ambiguous type for: has_or_had_format" warning.
# The base has_or_had_format slot has range: string, but VideoTranscript needs
# range: TranscriptFormat. This specialized slot provides the class-typed range.
#
# Creation date: 2026-01-16
# Rule compliance: 39 (RiC-O naming), 50 (ontology mapping)
id: https://nde.nl/ontology/hc/slot/has_or_had_transcript_format
name: has_or_had_transcript_format
title: Has or Had Transcript Format
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
default_prefix: hc
imports:
- linkml:types
- ../classes/TranscriptFormat
slots:
has_or_had_transcript_format:
slot_uri: hc:hasOrHadTranscriptFormat
description: |
The format of a transcript (plain text, structured, timestamped, etc.).
**USAGE**:
Specifies the structural format of a transcript. This slot is used
exclusively by VideoTranscript and related classes.
**TRANSCRIPT FORMATS**:
| Format | Description | Use Case |
|--------|-------------|----------|
| PLAIN_TEXT | Continuous text, no structure | Simple search indexing |
| PARAGRAPHED | Text broken into paragraphs | Human reading |
| STRUCTURED | Segments with speaker labels | Research, analysis |
| TIMESTAMPED | Segments with time markers | Navigation, subtitling |
**ONTOLOGY ALIGNMENT**:
- **Primary** (`slot_uri`): `hc:hasOrHadTranscriptFormat` - Heritage Custodian property
- **Related**: `schema:encodingFormat` - General encoding format
range: TranscriptFormat
required: false
inlined: true
close_mappings:
- schema:encodingFormat
examples:
- value: STRUCTURED
description: Text with speaker labels and paragraph breaks
- value: TIMESTAMPED
description: Segments with time codes for navigation
- value: PLAIN_TEXT
description: Continuous text without structure
annotations:
custodian_types: '["*"]'
custodian_types_rationale: "Transcript formats applicable to all custodian types with video content."

View file

@ -5,8 +5,8 @@
# for temporal relationships in heritage domain.
#
# Generation date: 2026-01-13
# Updated: 2026-01-16 - Added any_of pattern to resolve OWL ambiguous type warning
# Rule compliance: 38 (slot centralization + semantic URI), 39 (RiC-O naming), 42 (no prefix), 53 (generic slots)
# Updated: 2026-01-16 - Broadened range to uriorcurie per Rule 54
# Rule compliance: 38, 39, 42, 53, 54 (broaden range, not bespoke predicates)
id: https://nde.nl/ontology/hc/slot/has_or_had_type
name: has_or_had_type_slot
@ -24,7 +24,6 @@ default_prefix: hc
imports:
- linkml:types
- ../classes/TypeClass
slots:
has_or_had_type:
@ -37,28 +36,25 @@ slots:
may be historical - an entity may have been reclassified over time.
**Ontological Alignment**:
- **Primary** (`slot_uri`): `hc:hasOrHadType` - Heritage Custodian ObjectProperty
allowing class-valued ranges for type hierarchies
- **Primary** (`slot_uri`): `hc:hasOrHadType` - Heritage Custodian property
- **Exact**: `crm:P2_has_type` - CIDOC-CRM predicate for typing entities
(range: E55_Type, an ObjectProperty)
- **Close**: `dcterms:type` - Dublin Core type predicate
- **Related**: `schema:additionalType` - Schema.org for web semantics
**Usage**:
This is a GENERIC slot intended for reuse across multiple classes.
Classes may specialize the range in slot_usage to reference the
appropriate Type class hierarchy (e.g., StorageType, ZoneType, etc.).
Classes may narrow the range in slot_usage to reference specific Type class
hierarchies (e.g., StorageType, ZoneType, etc.).
**Range** (any_of pattern):
Accepts both string literals and TypeClass instances. This resolves the
OWL "Ambiguous type" warning by explicitly declaring both valid ranges.
**Range**: `uriorcurie` (Rule 54)
Broadened range to accept URI/CURIE references to type concepts.
This resolves OWL "Ambiguous type" warnings while maintaining semantic richness.
Classes can still narrow to specific Type classes via slot_usage.
**Cardinality**:
Multivalued - entities may have multiple type classifications.
any_of:
- range: string
- range: TypeClass
range: uriorcurie
required: false
multivalued: true
inlined_as_list: true
@ -87,27 +83,27 @@ slots:
zone_type, warehouse_type, unit_type, treatment_type, storage_type,
statement_type, sub_guide_type, wikidata_mapping_type
migration_date: "2026-01-13"
any_of_fix_date: "2026-01-16"
any_of_fix_purpose: |
Added any_of pattern with TypeClass to resolve OWL "Ambiguous type" warning.
gen-owl was reporting ambiguity because slot had range:string but classes
overrode to class types via slot_usage.
range_broadening_date: "2026-01-16"
range_broadening_rationale: |
Changed from range:string to range:uriorcurie per Rule 54.
This resolves OWL "Ambiguous type" warning while maintaining
semantic flexibility. Classes can narrow to specific Type classes
via slot_usage without causing DatatypeProperty/ObjectProperty ambiguity.
predicate_clarification: |
slot_uri references a PREDICATE (hc:hasOrHadType), not a class.
The range is polymorphic via any_of, accepting both strings and TypeClass instances.
comments:
- "Generic type slot for reuse across multiple classes"
- "any_of pattern: accepts both string and TypeClass values"
- "Range: uriorcurie - accepts URI/CURIE references to type concepts"
- "slot_uri=hc:hasOrHadType is a PREDICATE, not a class"
- "RiC-O naming: hasOrHad indicates potentially historical relationship"
- "Multivalued: entities may have multiple type classifications"
- "OWL fix: any_of pattern resolves Ambiguous type warning (2026-01-16)"
- "Rule 54: Broadened range instead of creating bespoke predicates"
examples:
- value: StorageType:ARCHIVE_DEPOT
description: "Storage typed as archive depot (class instance)"
- value: ZoneType:CLIMATE_CONTROLLED
description: "Environmental zone type (class instance)"
- value: "historic building"
description: "Free-text type description (string literal)"
- value: "hc:StorageType/ARCHIVE_DEPOT"
description: "Storage typed as archive depot (CURIE reference)"
- value: "hc:ZoneType/CLIMATE_CONTROLLED"
description: "Environmental zone type (CURIE reference)"
- value: "https://example.org/vocab/historic-building"
description: "External vocabulary reference (full URI)"

View file

@ -58,7 +58,7 @@ slots:
**Range**: `Any` (2026-01-16) - Allows uri/string values and URL class instances.
range: URL
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
required: false
multivalued: true
inlined: true

View file

@ -37,7 +37,7 @@ slots:
**Range**: `Any` (2026-01-16) - Allows uriorcurie values and class instances.
range: uriorcurie
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
multivalued: true
exact_mappings:

View file

@ -37,7 +37,7 @@ slots:
to resolve OWL ambiguous type warning when classes override range
to class types (e.g., CustodianObservation).
range: uriorcurie
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
exact_mappings:
- prov:wasDerivedFrom

View file

@ -55,7 +55,7 @@ slots:
**Cardinality**:
Multivalued - an entity may have equivalences in multiple systems.
range: string
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
required: false
multivalued: true
inlined_as_list: true

View file

@ -37,7 +37,7 @@ slots:
to resolve OWL ambiguous type warning when classes override range
to class types (e.g., ReconstructionActivity).
range: uriorcurie
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
exact_mappings:
- prov:wasGeneratedBy

View file

@ -60,7 +60,7 @@ slots:
**Cardinality**:
Multivalued - entities may have multiple classifications.
range: string
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
required: false
multivalued: true
inlined_as_list: true

View file

@ -62,7 +62,7 @@ slots:
**Cardinality**:
Multivalued - an entity may have multiple associations.
range: string
range: uriorcurie # Broadened per Rule 55 (2026-01-16) to resolve OWL ambiguous type warning
required: false
multivalued: true
inlined_as_list: true

View file

@ -5669,4 +5669,214 @@ fixes:
using Description class with description_type: from_owner. Migrated for symmetry
with to_owner_text which was migrated earlier in same session. Owner class not
used (existing from_owner slot provides structured reference). Original slot
archived to archive/from_owner_text_archived_20260115.yaml.'
archived to archive/from_owner_text_archived_20260115.yaml.'
- original_slot_id: https://nde.nl/ontology/hc/slot/about_text
revision:
- label: has_or_had_description
type: slot
- label: Description
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/address_type
revision:
- label: has_or_had_address
type: slot
- label: Address
type: class
- label: has_or_had_type
type: slot
- label: AddressType
type: class
- label: includes_or_included
type: slot
- label: AddressTypes
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/algorithm_name
revision:
- label: has_or_had_label
type: slot
- label: Label
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/algorithm_version
revision:
- label: has_or_had_version
type: slot
- label: Version
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/amount
revision:
- label: has_or_had_quantity
type: slot
- label: Quantity
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/applies_or_applied_to_call
revision:
- label: applies_or_applied_to
type: slot
- label: CallForApplication
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/approximation_level
revision:
- label: has_or_had_level
type: slot
- label: ApproximationLevel
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/archival_reference
revision:
- label: has_or_had_provenance
type: slot
- label: Provenance
type: class
- label: has_or_had_reference
type: slot
- label: Reference
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/area_value
revision:
- label: has_or_had_area
type: slot
- label: Area
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/arrangement_level
revision:
- label: has_or_had_level
type: slot
- label: ArrangementLevel
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/asserter_contact
revision:
- label: has_or_had_contact_person
type: slot
- label: ContactPerson
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/asserter_type
revision:
- label: has_or_had_type
type: slot
- label: AsserterType
type: class
- label: includes_or_included
type: slot
- label: AsserterTypes
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/asserter_version
revision:
- label: has_or_had_version
type: slot
- label: Version
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/assessment_date
revision:
- label: is_or_was_assessed
type: slot
- label: Assessment
type: class
- label: temporal_extent
type: slot
- label: TimeSpan
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audience_size
revision:
- label: serves_or_served
type: slot
- label: UserCommunity
type: class
- label: has_or_had_quantity
type: slot
- label: AudienceSize
type: class
- label: has_or_had_unit
type: slot
- label: MeasurementUnit
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audience_type
revision:
- label: serves_or_served
type: slot
- label: UserCommunity
type: class
- label: has_or_had_type
type: slot
- label: UserCommunityType
type: class
- label: includes_or_included
type: slot
- label: UserCommunityTypes
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audio_quality_score
revision:
- label: has_or_had_audio
type: slot
- label: Audio
type: class
- label: has_or_had_score
type: slot
- label: QualityScore
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audit_date
revision:
- label: is_or_was_audited
type: slot
- label: AuditEvent
type: class
- label: temporal_extent
type: slot
- label: TimeSpan
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audit_opinion
revision:
- label: is_or_was_audited
type: slot
- label: AuditEvent
type: class
- label: concludes_or_concluded
type: slot
- label: AuditOpinion
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/audit_status
revision:
- label: is_or_was_audited
type: slot
- label: AuditEvent
type: class
- label: has_or_had_status
type: slot
- label: AuditStatus
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/auditor_name
revision:
- label: is_or_was_audited
type: slot
- label: AuditEvent
type: class
- label: is_or_was_conducted_by
type: slot
- label: Auditor
type: class
- label: has_or_had_name
type: slot
- label: Name
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/author_affiliation
revision:
- label: is_or_was_affiliated_with
type: slot
- label: Affiliation
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/author_identifier
revision:
- label: has_or_had_identifier
type: slot
- label: Identifier
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/author_name
revision:
- label: has_or_had_name
type: slot
- label: Name
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/author_role
revision:
- label: has_or_had_role
type: slot
- label: AuthorRole
type: class

View file

@ -0,0 +1,40 @@
#!/bin/bash
# gen-heritage-owl.sh - Generate OWL ontology from Heritage Custodian LinkML schema
#
# Usage:
# ./scripts/gen-heritage-owl.sh [output-file] [additional-args...]
#
# Examples:
# ./scripts/gen-heritage-owl.sh # Output to stdout
# ./scripts/gen-heritage-owl.sh heritage_custodian.owl # Output to file
# ./scripts/gen-heritage-owl.sh -f ttl # Turtle format
#
# Why --type-objects is required:
# The Heritage Custodian schema uses generic slots (e.g., has_or_had_type,
# has_or_had_format) with `range: uriorcurie` that are narrowed by classes
# via slot_usage. While the range broadening to uriorcurie resolves most
# OWL ambiguity warnings, using --type-objects ensures consistent
# ObjectProperty treatment for all polymorphic slots.
#
# See also:
# - Rule 55: Broaden Generic Predicate Ranges (.opencode/rules/broaden-generic-predicate-ranges-rule.md)
# - Rule 53: Full Slot Migration (slot_fixes.yaml)
#
# Created: 2026-01-16
# Updated: 2026-01-16
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCHEMA_DIR="$(dirname "$SCRIPT_DIR")"
SCHEMA_FILE="${SCHEMA_DIR}/01_custodian_name_modular.yaml"
if [[ ! -f "$SCHEMA_FILE" ]]; then
echo "Error: Schema file not found: $SCHEMA_FILE" >&2
exit 1
fi
# Run gen-owl with --type-objects flag
# This treats types as objects (ObjectProperty) rather than literals (DatatypeProperty)
# which matches our polymorphic slot design pattern
exec gen-owl --type-objects "$SCHEMA_FILE" "$@"