Skip to content

Add Annotation/Note shape (W3C Web Annotation Vocabulary)#61

Draft
jeswr wants to merge 3 commits intosolid:mainfrom
jeswr:feat/annotation-shape
Draft

Add Annotation/Note shape (W3C Web Annotation Vocabulary)#61
jeswr wants to merge 3 commits intosolid:mainfrom
jeswr:feat/annotation-shape

Conversation

@jeswr
Copy link
Copy Markdown
Member

@jeswr jeswr commented Apr 23, 2026

Type of Change

* [x] New domain file
* [ ] Update existing domain file
* [ ] Documentation only

Domain

Domain file:        shapes/annotation.ttl
Purpose of domain:  Validation shape for Web Annotations covering the
                    common note, bookmark, comment, and highlight cases.
Intended use cases: Note-taking apps, bookmarking apps, and
                    annotation/highlight apps that store user-generated
                    content in a Solid Pod.

Shape Details

Shape name(s):      annotation_shape:AnnotationShape
Target class/node:  oa:Annotation
Files changed:      shapes/annotation.ttl (new)

Shape Change

* [x] New shape
* [ ] New version of existing shape
* [ ] Non-breaking constraint addition
* [ ] Documentation update

Description:

Adds a SHACL shape for oa:Annotation grounded in the W3C
Web Annotation Vocabulary
(Recommendation, 2017) and the
Web Annotation Data Model.

Constraints cover:

  • rdf:type (must include oa:Annotation)
  • oa:bodyValue (xsd:string, max 1) for inline textual bodies
  • oa:hasBody (IRI or blank node) for embedded or referenced bodies
  • oa:hasTarget (IRI or blank node, min 1)
  • oa:motivatedBy (IRI) – kept open per the Web Annotation Vocabulary
    motivation set; descriptions cite the common note-taking values
    (oa:bookmarking, oa:commenting, oa:highlighting).
  • dct:creator (IRI or blank node) – permits a WebID or an inline
    agent description; cardinality left open to allow co-creation
  • dct:created, dct:modified (xsd:dateTime, max 1 each)

Mutual exclusion of oa:bodyValue and oa:hasBody (Data Model
§3.2.4 SHOULD NOT) is documented in the property descriptions but not
enforced, in line with the catalogue's "Interoperability First"
design principle.


Immutability Confirmation

* [x] Existing constraints were not modified
* [x] Previously valid data remains valid
* [x] If behaviour changed, a new shape/version was introduced

(New file – no existing shapes were touched.)


Examples

Valid example

@prefix oa:  <http://www.w3.org/ns/oa#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

</annotations/note-1>
    a oa:Annotation ;
    oa:bodyValue "Reminder: read the W3C Web Annotation Recommendation." ;
    oa:hasTarget <https://www.w3.org/TR/annotation-vocab/> ;
    oa:motivatedBy oa:commenting ;
    dct:creator <https://example.org/profile/card#me> ;
    dct:created "2026-04-23T14:00:00Z"^^xsd:dateTime .

Invalid example

@prefix oa:  <http://www.w3.org/ns/oa#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

</annotations/note-2>
    a oa:Annotation ;
    # Missing oa:hasTarget – required by the shape (min 1).
    oa:bodyValue "An annotation with no target." .

Compatibility

* [x] Fully backwards compatible
* [ ] May cause new validation failures
* [ ] Breaking change

New domain file. No existing shape touched.


Validation

* [x] SHACL validation run
* [x] Example data tested

Tools used: pyshacl, plus the repository's scripts/validate-shacl-shapes-file.py, scripts/check-metadata-and-immutability-file.py, and scripts/check-namespaces-and-names-file.py.


Reviewer Checklist

* [ ] Immutability respected
* [ ] Targeting is correct
* [ ] Constraints justified
* [ ] Examples match expected behaviour

jeswr and others added 3 commits April 23, 2026 02:23
Adds a SHACL shape for oa:Annotation covering the common note,
bookmark, comment, and highlight cases. Grounded in the W3C Web
Annotation Vocabulary (Recommendation, 2017).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Drop sh:in restriction on oa:motivatedBy so the shape does not reject
  conforming oa:Annotation instances that use motivations outside the
  common note-taking subset (e.g., oa:tagging, oa:replying).
- Permit dct:creator as either a WebID IRI or an embedded agent
  description, matching the W3C Web Annotation Data Model.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Note in oa:bodyValue and oa:hasBody descriptions that the Web
  Annotation Data Model (§3.2.4) says an annotation SHOULD NOT have
  both. The shape stays permissive (interoperability first) but flags
  the constraint to consumers.
- Drop sh:maxCount 1 on dct:creator since the Web Annotation Data
  Model permits multiple creators (co-creation).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 23, 2026 01:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new SHACL domain file to validate W3C Web Annotation (oa:Annotation) data commonly produced by note-taking/bookmarking/highlighting apps in Solid Pods.

Changes:

  • Introduces annotation_shape:AnnotationShape targeting oa:Annotation.
  • Adds property constraints for body (oa:bodyValue / oa:hasBody), target (oa:hasTarget), motivation (oa:motivatedBy), creator (dct:creator), and timestamps (dct:created / dct:modified).
  • Includes shape metadata (created date, term status, sources/references) aligned with repository validation scripts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread shapes/annotation.ttl
Comment on lines +41 to +46
sh:path oa:bodyValue ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
sh:name "Body Value" ;
sh:description "Textual content of the annotation body, used for plain-text comments or notes (Web Annotation Vocabulary, oa:bodyValue). SHOULD NOT be combined with oa:hasBody on the same annotation." ;
sh:codeIdentifier "bodyValue";
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oa:bodyValue is constrained to xsd:string, which will fail validation for language-tagged literals (datatype rdf:langString) that are common for user-generated annotation text. Consider allowing both xsd:string and rdf:langString (e.g., with sh:or), or relaxing the datatype constraint to improve interoperability with Web Annotation data in the wild.

Copilot uses AI. Check for mistakes.
Comment thread shapes/annotation.ttl
sh:path oa:motivatedBy ;
sh:nodeKind sh:IRI ;
sh:name "Motivation" ;
sh:description "Why the annotation was created (Web Annotation Vocabulary, oa:Motivation). Common note-taking values are oa:bookmarking, oa:commenting, and oa:highlighting." ;
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The oa:motivatedBy property description cites oa:Motivation (the class) even though the constraint is on oa:motivatedBy (the property). Updating the description to reference the property (and optionally the expected range) would avoid confusion for shape consumers.

Suggested change
sh:description "Why the annotation was created (Web Annotation Vocabulary, oa:Motivation). Common note-taking values are oa:bookmarking, oa:commenting, and oa:highlighting." ;
sh:description "Why the annotation was created (Web Annotation Vocabulary, oa:motivatedBy). Values are typically motivation IRIs such as oa:bookmarking, oa:commenting, and oa:highlighting." ;

Copilot uses AI. Check for mistakes.
@jeswr jeswr marked this pull request as draft April 23, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants