From 684d79935a4f9e16a147be2dc8ca98613ceaaa4a Mon Sep 17 00:00:00 2001 From: kempersc Date: Sat, 14 Feb 2026 20:11:46 +0100 Subject: [PATCH] Enhance descriptions and update slot references across multiple YAML files for improved clarity and consistency --- .../rules/class-description-quality-rule.md | 102 ++++++++++ .../rules/linkml-yaml-best-practices-rule.md | 181 ++++++++++++++++++ schemas/20251121/linkml/manifest.json | 2 +- .../modules/classes/AcademicArchive.yaml | 9 +- .../classes/AcademicArchiveRecordSetType.yaml | 59 ++++-- .../linkml/modules/classes/CateringPlace.yaml | 4 +- .../linkml/modules/classes/DarkArchive.yaml | 4 +- .../classes/DataServiceEndpointType.yaml | 4 +- .../classes/DataServiceEndpointTypes.yaml | 16 +- .../modules/classes/LinkedInProfile.yaml | 4 +- .../modules/classes/VideoAudioAnnotation.yaml | 6 +- .../modules/classes/VideoTimeSegment.yaml | 4 +- .../20260202_matang/evaluated_through.yaml | 58 ++++++ .../modules/slots/has_access_policy.yaml | 2 +- 14 files changed, 412 insertions(+), 43 deletions(-) create mode 100644 .opencode/rules/class-description-quality-rule.md create mode 100644 .opencode/rules/linkml-yaml-best-practices-rule.md create mode 100644 schemas/20251121/linkml/modules/slots/20260202_matang/evaluated_through.yaml diff --git a/.opencode/rules/class-description-quality-rule.md b/.opencode/rules/class-description-quality-rule.md new file mode 100644 index 0000000000..f44ed5da05 --- /dev/null +++ b/.opencode/rules/class-description-quality-rule.md @@ -0,0 +1,102 @@ +# Class Description Quality Rule + +## Rule: Write Dictionary-Style Definitions Without Repeating the Class Name + +When writing class descriptions, follow these principles: + +### 1. No Repetition of Class Name Components + +**WRONG:** +```yaml +AcademicArchiveRecordSetType: + description: >- + A classification type for archival record sets created by academic + institutions. This class represents the record set type... +``` + +**CORRECT:** +```yaml +AcademicArchiveRecordSetType: + description: >- + Category for grouping documentary materials accumulated by tertiary + educational institutions during their administrative, academic, and + operational activities. +``` + +The description should define the concept using synonyms and related terms, not repeat words from the class name. + +### 2. No Structured Data or Meta-Discussion in Descriptions + +Descriptions should contain only the definition. Do not include: +- Alignment explanations (use `broad_mappings`, `close_mappings`, `exact_mappings`) +- Pattern explanations (use `see_also`, `comments`) +- Usage examples (use `examples:` annotation) +- Rationale for mappings (use `comments:` or `annotations:`) + +**WRONG:** +```yaml +description: >- + A type for X. + + **RiC-O Alignment**: Maps to rico:RecordSetType because... + + **Pattern**: This is part of a dual-class pattern with Y. + + **Examples**: Administrative fonds, student records... +``` + +**CORRECT:** +```yaml +description: >- + Category for grouping documentary materials accumulated by tertiary + educational institutions. + +broad_mappings: + - rico:RecordSetType +see_also: + - AcademicArchive +examples: + - value: {...} + description: Administrative fonds containing governance records +``` + +### 3. Use Folded Block Scalar (`>-`) for Descriptions + +Use `>-` (folded, strip) instead of `|` (literal) to ensure clean paragraph formatting in generated documentation. + +**WRONG:** +```yaml +description: | + A type for X. + This spans multiple lines. +``` + +**CORRECT:** +```yaml +description: >- + A type for X. This will be formatted as a single clean paragraph + in the generated documentation. +``` + +### 4. Use LinkML `examples:` Annotation for Examples + +Structure examples properly with `value:` and `description:` keys. + +```yaml +examples: +- value: + has_type: hc:ArchiveOrganizationType + has_label: University Administrative Records + description: Administrative fonds containing governance records +``` + +## Summary + +| Element | Placement | +|---------|-----------| +| Definition | `description:` (concise, no repetition) | +| Ontology mappings | `exact_mappings`, `broad_mappings`, etc. | +| Related concepts | `see_also:` | +| Usage notes | `comments:` | +| Metadata | `annotations:` | +| Examples | `examples:` with `value` and `description` | diff --git a/.opencode/rules/linkml-yaml-best-practices-rule.md b/.opencode/rules/linkml-yaml-best-practices-rule.md new file mode 100644 index 0000000000..1c237ef1f5 --- /dev/null +++ b/.opencode/rules/linkml-yaml-best-practices-rule.md @@ -0,0 +1,181 @@ +# LinkML YAML Best Practices Rule + +## Rule: Follow LinkML Conventions for Valid, Interoperable Schema Files + +### 1. equals_expression Anti-Pattern + +`equals_expression` is for dynamic formula evaluation (e.g., `"{age_in_years} * 12"`). Never use it for static value constraints. + +**WRONG:** +```yaml +slot_usage: + has_type: + equals_expression: '["hc:ArchiveOrganizationType"]' + hold_record_set: + equals_expression: '["hc:Fonds", "hc:Series"]' +``` + +**CORRECT** (single value): +```yaml +slot_usage: + has_type: + equals_string: "hc:ArchiveOrganizationType" +``` + +**CORRECT** (multiple allowed values - if classes): +```yaml +slot_usage: + hold_record_set: + any_of: + - range: UniversityAdministrativeFonds + - range: StudentRecordSeries + - range: FacultyPaperCollection +``` + +**CORRECT** (multiple allowed values - if literals): +```yaml +slot_usage: + status: + equals_string_in: + - "active" + - "inactive" + - "pending" +``` + +### 2. Declare All Used Prefixes + +Every CURIE prefix used in the file must be declared in the `prefixes:` block. + +**WRONG:** +```yaml +prefixes: + linkml: https://w3id.org/linkml/ + skos: http://www.w3.org/2004/02/skos/core# +slot_usage: + has_type: + equals_string: "hc:ArchiveOrganizationType" # hc: not declared! +``` + +**CORRECT:** +```yaml +prefixes: + linkml: https://w3id.org/linkml/ + hc: https://nde.nl/ontology/hc/ + skos: http://www.w3.org/2004/02/skos/core# +default_prefix: hc +slot_usage: + has_type: + equals_string: "hc:ArchiveOrganizationType" +``` + +### 3. Import Referenced Classes + +When using external classes in `is_a`, `range`, or other references, import them. + +**WRONG:** +```yaml +imports: + - linkml:types +classes: + AcademicArchive: + is_a: ArchiveOrganizationType # Not imported! + slot_usage: + related_to: + range: WikidataAlignment # Not imported! +``` + +**CORRECT:** +```yaml +imports: + - linkml:types + - ../classes/ArchiveOrganizationType + - ../classes/WikidataAlignment +classes: + AcademicArchive: + is_a: ArchiveOrganizationType + slot_usage: + related_to: + range: WikidataAlignment +``` + +### 4. Quote Regex Patterns and Annotation Values + +**Regex patterns:** +```yaml +# WRONG +pattern: ^Q[0-9]+$ + +# CORRECT +pattern: "^Q[0-9]+$" +``` + +**Annotation values (must be strings):** +```yaml +# WRONG +annotations: + specificity_score: 0.1 + +# CORRECT +annotations: + specificity_score: "0.1" +``` + +### 5. Remove Unused Imports + +Only import slots and classes that are actually used in the file. + +**WRONG:** +```yaml +imports: + - ../slots/has_scope # Never used in slots: or slot_usage: + - ../slots/has_score + - ../slots/has_type +``` + +**CORRECT:** +```yaml +imports: + - ../slots/has_score + - ../slots/has_type +``` + +### 6. Slot Usage Requires Slot Presence + +A slot referenced in `slot_usage:` must either be: +- Listed in the `slots:` array, OR +- Inherited from a parent class via `is_a` + +**WRONG:** +```yaml +classes: + MyClass: + slots: + - has_type + slot_usage: + has_type: {...} + identified_by: {...} # Not in slots: and not inherited! +``` + +**CORRECT:** +```yaml +classes: + MyClass: + slots: + - has_type + - identified_by + slot_usage: + has_type: {...} + identified_by: {...} +``` + +## Checklist for Class Files + +- [ ] All prefixes used in CURIEs are declared +- [ ] `default_prefix` set if module belongs to that namespace +- [ ] All referenced classes are imported +- [ ] All used slots are imported +- [ ] No `equals_expression` with static JSON arrays +- [ ] Regex patterns are quoted +- [ ] Annotation values are quoted strings +- [ ] No unused imports +- [ ] `slot_usage` only references slots that exist (via slots: or inheritance) diff --git a/schemas/20251121/linkml/manifest.json b/schemas/20251121/linkml/manifest.json index 021a846ce7..5a25130f6d 100644 --- a/schemas/20251121/linkml/manifest.json +++ b/schemas/20251121/linkml/manifest.json @@ -1,5 +1,5 @@ { - "generated": "2026-02-14T13:41:49.801Z", + "generated": "2026-02-14T19:11:47.040Z", "schemaRoot": "/schemas/20251121/linkml", "totalFiles": 2369, "categoryCounts": { diff --git a/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml b/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml index 31bffecf37..7974cf06cd 100644 --- a/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml +++ b/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml @@ -21,7 +21,14 @@ classes: AcademicArchive: is_a: ArchiveOrganizationType class_uri: schema:ArchiveOrganization - description: Archive of a higher education institution (university, college, polytechnic). + description: | + An organizational unit or repository functioning as the official archival custodian + for a higher education institution (e.g., a university, college, or polytechnic). + It is responsible for acquiring, preserving, and providing access to the institution's official administrative records, historical + memory, faculty papers, and documentation of student and campus life. This class specifically represents the custodial + organization managing the collections, rather than the archival record sets themselves, + and is conceptually distinct from institutional repositories that primarily manage + published scholarly research outputs. slots: - has_type - hold_record_set diff --git a/schemas/20251121/linkml/modules/classes/AcademicArchiveRecordSetType.yaml b/schemas/20251121/linkml/modules/classes/AcademicArchiveRecordSetType.yaml index 21bf424214..a34d8c7b89 100644 --- a/schemas/20251121/linkml/modules/classes/AcademicArchiveRecordSetType.yaml +++ b/schemas/20251121/linkml/modules/classes/AcademicArchiveRecordSetType.yaml @@ -1,32 +1,59 @@ id: https://nde.nl/ontology/hc/class/AcademicArchiveRecordSetType name: AcademicArchiveRecordSetType -title: AcademicArchive Record Set Type +title: Academic Archive Record Set Type prefixes: linkml: https://w3id.org/linkml/ + hc: https://nde.nl/ontology/hc/ schema: http://schema.org/ skos: http://www.w3.org/2004/02/skos/core# rico: https://www.ica.org/standards/RiC/ontology# wd: http://www.wikidata.org/entity/ +default_prefix: hc imports: - linkml:types - - ../slots/has_scope + - ../classes/CollectionType + - ../classes/WikidataAlignment - ../slots/has_score - ../slots/has_type - ../slots/related_to classes: AcademicArchiveRecordSetType: - description: A rico:RecordSetType for classifying collections of academic and - higher education institutional records. + description: >- + Category for grouping documentary materials accumulated by tertiary educational + institutions during their administrative, academic, and operational activities. + Distinguishes the classification of holdings from the repository organization + responsible for their custody. + examples: + - value: + has_type: hc:ArchiveOrganizationType + has_label: University Administrative Records + related_to: wd:Q27032435 + description: Administrative fonds containing governance records, committee minutes, and policy documents + - value: + has_type: hc:ArchiveOrganizationType + has_label: Student Records Series + related_to: wd:Q27032435 + description: Enrollment records, academic transcripts, and graduation documentation + - value: + has_type: hc:ArchiveOrganizationType + has_label: Faculty Papers Collection + related_to: wd:Q27032435 + description: Research documentation, teaching materials, and correspondence + - value: + has_type: hc:ArchiveOrganizationType + has_label: Campus Documentation Collection + related_to: wd:Q27032435 + description: Photographs, university publications, and audiovisual materials is_a: CollectionType class_uri: rico:RecordSetType slots: - has_type - has_score - - has_scope - related_to comments: - - Collection type class for academic/higher education record sets + - Record set TYPE classification, not the custodian organization - Part of dual-class pattern with AcademicArchive (custodian type) + - Use AcademicArchive for the archive organization; use this class for collection types structured_aliases: - literal_form: Hochschularchivbestand in_language: de @@ -38,25 +65,19 @@ classes: in_language: nl slot_usage: has_type: - equals_expression: '["hc:ArchiveOrganizationType"]' + equals_string: "hc:ArchiveOrganizationType" related_to: range: WikidataAlignment inlined: true - exact_mappings: - - wd:Q27032435 - - rico:RecordSetType broad_mappings: - - wd:Q27032435 - close_mappings: + - rico:RecordSetType - skos:Concept + close_mappings: + - wd:Q27032435 see_also: - AcademicArchive - rico:RecordSetType - - UniversityAdministrativeFonds - - StudentRecordSeries - - FacultyPaperCollection - - CampusDocumentationCollection annotations: - specificity_score: 0.1 - specificity_rationale: Generic utility class/slot created during migration - custodian_types: '[''*'']' + specificity_score: "0.3" + specificity_rationale: Specific to academic/higher education archival collections + custodian_types: "['AcademicArchive']" diff --git a/schemas/20251121/linkml/modules/classes/CateringPlace.yaml b/schemas/20251121/linkml/modules/classes/CateringPlace.yaml index 94a23a3a40..c95c4b9f40 100644 --- a/schemas/20251121/linkml/modules/classes/CateringPlace.yaml +++ b/schemas/20251121/linkml/modules/classes/CateringPlace.yaml @@ -21,7 +21,7 @@ imports: - ../slots/has_capacity - ../slots/require - ../slots/has_user - - ../slots/20260202_matang/serves_visitors_only + - ../slots/has_user_category prefixes: linkml: https://w3id.org/linkml/ hc: https://nde.nl/ontology/hc/ @@ -67,7 +67,7 @@ classes: - require - has_capacity - has_user - - serves_visitors_only + - has_user_category - has_score - derive_from - generated_by diff --git a/schemas/20251121/linkml/modules/classes/DarkArchive.yaml b/schemas/20251121/linkml/modules/classes/DarkArchive.yaml index a2f95c2747..51b0d3ff6e 100644 --- a/schemas/20251121/linkml/modules/classes/DarkArchive.yaml +++ b/schemas/20251121/linkml/modules/classes/DarkArchive.yaml @@ -20,7 +20,7 @@ imports: - ../slots/has_type - ../slots/hold_record_set - ../slots/has_objective - - ../slots/20260202_matang/refers_to_access_policy + - ../slots/has_access_policy classes: DarkArchive: is_a: CustodianType @@ -30,7 +30,7 @@ classes: - has_deadline - hold_record_set - has_objective - - refers_to_access_policy + - has_access_policy - has_score - identified_by description: "Archive preserving materials for future use but with NO CURRENT ACCESS.\n\n**Wikidata**: Q112796578 (Dark Archive)\n\n**DEFINITION**:\n\nDark Archive is a preservation repository where materials are stored with \nNO ACCESS provided to users. The primary purpose is long-term preservation\nrather than current use. Access may be triggered by specific future events.\n\n**ACCESS SPECTRUM** (Light/Dim/Dark classification):\n\n| Type | Access Level | Purpose |\n|------|--------------|---------|\n| Light Archive (Q112815447) | Broadly accessible | Discovery & use |\n| Dim Archive (Q112796779) | Limited access | Selective access |\n| **Dark Archive** | No current access | Preservation only |\n\n**COMMON USE CASES**:\n\n1. **Digital Preservation**\n - Trusted Digital Repositories (TDR)\n - Backup/disaster recovery copies\n - Integrity verification archives\n\n2. **Rights-Restricted Content**\n - Orphan works awaiting rights clearance\n - Embargoed materials\n - Donor\ diff --git a/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml b/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml index 8fb12635ec..10bc2a2d88 100644 --- a/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml +++ b/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml @@ -16,7 +16,7 @@ imports: - ../slots/has_method - ../slots/has_score - ../slots/used_in - - ../slots/20260202_matang/specification_url + - ../slots/has_specification classes: DataServiceEndpointType: abstract: true @@ -68,7 +68,7 @@ classes: - https://www.w3.org/TR/vocab-dcat-3/#Class:Data_Service slots: - has_score - - specification_url + - has_specification - has_format - has_method - used_in diff --git a/schemas/20251121/linkml/modules/classes/DataServiceEndpointTypes.yaml b/schemas/20251121/linkml/modules/classes/DataServiceEndpointTypes.yaml index 6c79c1ecd0..44117475e6 100644 --- a/schemas/20251121/linkml/modules/classes/DataServiceEndpointTypes.yaml +++ b/schemas/20251121/linkml/modules/classes/DataServiceEndpointTypes.yaml @@ -16,7 +16,7 @@ imports: - ../slots/has_format - ../slots/has_method - ../slots/has_score - - ../slots/20260202_matang/specification_url + - ../slots/has_specification classes: SRUEndpoint: is_a: DataServiceEndpointType @@ -47,7 +47,7 @@ classes: ' slot_usage: - specification_url: + has_specification: ifabsent: uri(http://www.loc.gov/standards/sru/) has_format: ifabsent: string(application/xml) @@ -93,7 +93,7 @@ classes: ' slot_usage: - specification_url: + has_specification: ifabsent: uri(https://opensearch.org/) has_format: equals_expression: '["application/opensearchdescription+xml", "application/atom+xml", @@ -142,7 +142,7 @@ classes: ' slot_usage: - specification_url: + has_specification: ifabsent: uri(https://iiif.io/api/image/) has_format: equals_expression: '["image/jpeg", "image/png", "image/tiff", "image/webp"]' @@ -189,7 +189,7 @@ classes: ' slot_usage: - specification_url: + has_specification: ifabsent: uri(https://iiif.io/api/presentation/) has_format: ifabsent: string(application/ld+json) @@ -233,7 +233,7 @@ classes: ' slot_usage: - specification_url: + has_specification: ifabsent: uri(https://www.w3.org/TR/sparql11-protocol/) has_format: equals_expression: '["application/sparql-results+json", "application/sparql-results+xml", @@ -276,7 +276,7 @@ classes: ' slot_usage: - specification_url: + has_specification: ifabsent: uri(https://graphql.org/) has_format: ifabsent: string(application/json) @@ -317,7 +317,7 @@ classes: ' slot_usage: - specification_url: + has_specification: ifabsent: uri(https://www.rfc-editor.org/rfc/rfc4287) has_format: ifabsent: string(application/atom+xml) diff --git a/schemas/20251121/linkml/modules/classes/LinkedInProfile.yaml b/schemas/20251121/linkml/modules/classes/LinkedInProfile.yaml index 0573fe7b36..2d50c2e9ef 100644 --- a/schemas/20251121/linkml/modules/classes/LinkedInProfile.yaml +++ b/schemas/20251121/linkml/modules/classes/LinkedInProfile.yaml @@ -37,7 +37,7 @@ imports: - ../slots/has_url - ../slots/refer_to - ../slots/has_name - - ../slots/20260202_matang/skill + - ../slots/has_skill - ../slots/employed_by - ../slots/temporal_extent # default_range: string @@ -122,7 +122,7 @@ classes: - has_url - refer_to - has_name - - skill + - has_skill - has_score slot_usage: has_name: diff --git a/schemas/20251121/linkml/modules/classes/VideoAudioAnnotation.yaml b/schemas/20251121/linkml/modules/classes/VideoAudioAnnotation.yaml index a30614a766..0e9cb7731d 100644 --- a/schemas/20251121/linkml/modules/classes/VideoAudioAnnotation.yaml +++ b/schemas/20251121/linkml/modules/classes/VideoAudioAnnotation.yaml @@ -27,7 +27,7 @@ imports: - ../slots/has_silence - ../slots/has_ratio - ../slots/has_speaker - - ../slots/20260202_matang/speaker_label + - ../slots/has_speaker - ../slots/has_spoken_words - ../slots/temporal_extent prefixes: @@ -76,7 +76,7 @@ classes: # - contain - DUPLICATE REMOVED - has_sound - has_speaker - - speaker_label + - has_speaker - has_spoken_words - has_spoken_words - has_confidence_measure @@ -201,7 +201,7 @@ classes: - in_language - begin_of_the_begin - has_speaker - - speaker_label + - has_speaker - has_spoken_words - has_score slot_usage: diff --git a/schemas/20251121/linkml/modules/classes/VideoTimeSegment.yaml b/schemas/20251121/linkml/modules/classes/VideoTimeSegment.yaml index b6bce59f85..62ae695137 100644 --- a/schemas/20251121/linkml/modules/classes/VideoTimeSegment.yaml +++ b/schemas/20251121/linkml/modules/classes/VideoTimeSegment.yaml @@ -9,7 +9,7 @@ imports: - ../slots/indexed_as - ../slots/has_text - ../slots/has_speaker - - ../slots/20260202_matang/speaker_label + - ../slots/has_speaker prefixes: linkml: https://w3id.org/linkml/ hc: https://nde.nl/ontology/hc/ @@ -147,7 +147,7 @@ classes: - indexed_as - has_text - has_speaker - - speaker_label + - has_speaker - has_score - generated_by - begin_of_the_begin diff --git a/schemas/20251121/linkml/modules/slots/20260202_matang/evaluated_through.yaml b/schemas/20251121/linkml/modules/slots/20260202_matang/evaluated_through.yaml new file mode 100644 index 0000000000..8d586f2a82 --- /dev/null +++ b/schemas/20251121/linkml/modules/slots/20260202_matang/evaluated_through.yaml @@ -0,0 +1,58 @@ +id: https://nde.nl/ontology/hc/slot/evaluated_through +name: evaluated_through +title: Evaluated Through +prefixes: + linkml: https://w3id.org/linkml/ + hc: https://nde.nl/ontology/hc/ + prov: http://www.w3.org/ns/prov# + schema: http://schema.org/ + dcterms: http://purl.org/dc/terms/ + crm: http://www.cidoc-crm.org/cidoc-crm/ + skos: http://www.w3.org/2004/02/skos/core# + rdfs: http://www.w3.org/2000/01/rdf-schema# + org: http://www.w3.org/ns/org# + xsd: http://www.w3.org/2001/XMLSchema# +imports: +- linkml:types +default_prefix: hc +slots: + evaluated_through: + description: | + Is assessed by, Measured via, or Judged using a specific method, metric, test, or process to determine quality, performance, or value. + + + Guides data curation: + + - **Priority level**: High/medium/low priority for re-investigation + + - **Review triggers**: What would prompt re-classification attempt + + - **Resource requirements**: Specialist knowledge, funding, access needed + + - **Timeline**: When next review is scheduled + + - **Outcome scenarios**: Keep record, remove if no progress, upgrade confidence + + - **Escalation path**: When to involve external experts + + + Review status ensures unspecified records don''t stagnate. + + + Examples: + + - "Requires specialist research, Low priority, Consider removing if no evidence emerges" + + - "High priority - institution recently mentioned in journal, Re-investigate within 3 months" + + - "Medium priority - waiting for archival collection to be cataloged, Review in 2026" + + - "Low priority - defunct since 1920s, minimal heritage significance" + + ' + range: string + slot_uri: hc:evaluatedThrough + annotations: + custodian_types: '["*"]' + aliases: + - review_status \ No newline at end of file diff --git a/schemas/20251121/linkml/modules/slots/has_access_policy.yaml b/schemas/20251121/linkml/modules/slots/has_access_policy.yaml index 2b470f17f7..5f97263d9f 100644 --- a/schemas/20251121/linkml/modules/slots/has_access_policy.yaml +++ b/schemas/20251121/linkml/modules/slots/has_access_policy.yaml @@ -111,7 +111,7 @@ slots: - restriction_category - restriction_description - restriction_type - - refers_to_access_policy + - refers_to_access_policys comments: - schema:conditionsOfAccess is semantically closer (conditions for access) than schema:publishingPrinciples (editorial principles). - |