Introduction

Some use cases require a role to be associated with a body or target resource, for example distinguishing between a body that's a comment or justification for a second body which is an edit to be made to the target resource. The distinction between tagging a resource, either with a string or a URI, and describing it is also a common pattern for a single annotation. The Web Annotation Data Model [[annotation-model]] can currently only support the inference of a single role from the Motivation associated with the Annotation, or from the specific structures added to accomodate tagging. This proposal takes the results of discussion within the Working Group and lays out concrete options, based on general consensus from the weekly teleconferences.

Requirements and Desiderata

The following are the requirements and desiderata for the change to the model.

The model ...

  1. MUST allow the addition of roles to individual bodies
  2. SHOULD use the same construction for tags as other roles
  3. SHOULD allow the addition of roles to individual targets
  4. MUST allow for domain-specific extension of the set of roles
  5. SHOULD use the existing motivation structure
  6. MUST be usable in a Linked Data environment
  7. SHOULD follow Linked Data best practices
  8. MUST produce a JSON-LD serialization that is easy to use in a pure JSON context
  9. MUST NOT require clients to use any part of the RDF stack to accomplish common tasks
  10. SHOULD allow for graceful degradation when a particular role is not recognized by a client application

Additional Design Criteria

While not requirements, there are additional design criteria that are considered important to keep in mind:

Related Changes

Not related specifically to the issue of roles, the discussion has also brought up other issues that could be solved at the same time, particularly around making the serialization more friendly to non Linked Data developers:
  1. Use id and type instead of @id and @type in JSON-LD to make javascript dot notation viable
  2. The model SHOULD allow for the type of a resource to be inferred where possible, rather than stated explicitly in the serialization. In particular, the following types should be explicitly OPTIONAL:
    • EmbeddedContent
    • SpecificResource
    • All of the dctypes and/or schema.org broad format classes
    • CSSStyle
  3. The naming of the properties and classes SHOULD be understandable by developers without knowing the Linked Data background

Changes to the Data Model

The following summarizes the changes proposed to fulfill the above requirements, with examples and further description below.

  1. Create a new predicate oa:hasRole, with a JSON-LD mapping of role, and associated with instances of SpecificResource
  2. Create a new predicate oa:text to replace rdf:value when used with EmbeddedContent, with a JSON-LD mapping of text
  3. Types that are easily inferred SHOULD be omitted from the serialization
  4. Remove Tag and SemanticTag classes in favor of SpecificResource with roles
  5. Use content as the key in the JSON-LD for the relationship between the SpecificResource and the full resource (currently source)
  6. Consider:
    1. Requiring the use of SpecificResource for annotation bodies
      1. Also requiring their use for targets
    2. Renaming oa:hasSource to oa:hasContent
    3. Removing oa:motivatedBy completely
    4. Allowing hasRole on EmbeddedContent for bodies, with a new subclass
    5. Renaming EmbeddedContent and SpecificResource, either in the model or the JSON-LD context (suggestions reqeusted)

Options that were considered and discarded from consideration include:

Proposed Model Revision

The SpecificResource construction allows annotation specific information about a resource (either body or target) to be added in a single, consistent location. As this construction already exists, and role is an annotation specific feature, it is appropriate to associate oa:hasRole with the SpecificResource. This allows the same resource to have different roles in different annotations, for example a page used as a semantic tag and as a comment.

The examples below demonstrate the use of oa:text as a replacement for rdf:value when used with EmbeddedContent. This makes the type of body clearer without an explicit type, plus rdf:value is a bit of a stretch in terms of semantics. Other names for the predicate are possible and can be discussed once the pattern is established. They also demonstrate the use of content as the mapping for oa:hasSource, but does not rename it in the ontology.

The newly OPTIONAL types are omitted from the examples below to demonstrate that their inclusion is unnecessary. The examples demonstrate the removal of Tag and SemanticTag classes, as they would be redundant with the role of tagging.

Resource Example

Associating the commenting role with a body that has a URI.

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": {
    "role": "commenting",
    "content": "http://example.org/body1"
  } 
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody [
        oa:hasRole oa:commenting ;
        oa:hasSource <http://example.org/body1>
    ]

Text Example

Associating the commenting role with textual content carried in the annotation.

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": {
    "role": "commenting",
    "content": {"text": "I love this thing"}
  } 
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody [
        oa:hasRole oa:commenting ;
        oa:hasSource [ oa:text "I love this thing" ]
    ]

Text Tag Example

Associating the tagging role with textual content carried in the annotation.

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": {
    "role": "tagging",
    "content": {"text": "tag"}
  } 
}
<http://example.org/anno1> a oa:Annotation ;
  oa:hasTarget <http://example.org/target1> ;
  oa:hasBody [
    oa:hasRole oa:tagging ;
    oa:hasSource [ oa:text "tag" ]
  ]

Multiple Text Tags

Associating the tagging role with each of multiple tags in the same annotation.

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": [
    {
      "role": "tagging",
      "content": {"text": "tag"}
    },
    {
      "role": "tagging",
      "content": {"text": "another"}
    }
  ]
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody [
        oa:hasRole oa:tagging ;
        oa:hasSource [ oa:text "tag" ]
    ], [
        oa:hasRole oa:tagging ;
        oa:hasSource [ oa:text "another" ]
    ]

Semantic Tag Example

Associating the tagging role with a URI, often called a semantic tag as it avoids the ambiguity of plain text strings.

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": {
    "role": "tagging",
    "content": "http://example.org/tag1"
  } 
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody [
        oa:hasRole oa:tagging ;
        oa:hasSource <http://example.org/tag1>
    ]

Multiple Bodies Example

An annotation with multiple bodies with different roles. It associates a URI as a tag, and some textual content as a comment, with the same target resource

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": [{
      "role": "tagging", 
      "content": "http://example.org/tag1"
    },
    {
      "role": "commenting", 
      "content": {
        "text": "I love this thing",
        "format": "text/html",
        "language": "en"
      }
    }
  ]
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody [
        oa:hasRole oa:tagging ;
        oa:hasSource <http://example.org/tag1>
    ],
    [
        oa:hasRole oa:commenting ;
        oa:hasSource [ 
            oa:text "I love this thing" ;
            dc:format "text/html" ;
            dc:language "en"
        ]
    ]

Multiple Bodies Example (2)

An annotation with multiple bodies with different roles. It associates a comment and an edit with a specific segment of a resource.

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {
    "selector": {
      "type": "TextQuoteSelector",
      "prefix": "This is before a ",
      "exact": "misteak",
      "suffix": " and this is after it."
    },
    "content": {"id": "http://example.com/target.html"}
  },
  "body": [
    {
      "role": "commenting", 
      "content": {
        "text": "There is a <b>typo</b> here, it should be 'mistake'.",
        "format": "text/html",
        "language": "en"
      }
    },
    {
      "role": "editing",
      "content": {
        "text": "mistake",
        "format": "text/plain",
        "language": "en"
      }
    }
  ]
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget  [
      oa:hasSelector [
        a oa:TextQuoteSelector ;
        oa:prefix "This is before a " ;
        oa:exact "misteak" ;
        oa:suffix " and this is after it."
      ]
    ];
    oa:hasBody [
        oa:hasRole oa:commenting ;
        oa:hasSource [ 
            oa:text "There is a <b>typo</b> here, it should be 'mistake'." ;
            dc:format "text/html" ;
            dc:language "en"
        ]
    ],
    [
        oa:hasRole oa:editing ;
        oa:hasSource [ 
            oa:text "mistake" ;
            dc:format "text/plain" ;
            dc:language "en"
        ]
    ]

Target with Role Example

A simple highlight is the role of the target in the annotation. The annotation is highlighting the target. There may be no body at all in this case.

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {
      "role": "highlighting",
      "content": "http://example.org/book1#para1"
    }
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget [
        oa:hasRole oa:highlighting ;
        oa:hasSource  ]

Multiple Targets with Roles Example

A hypothetical example of the use of roles with targets, rather than bodies. This annotation has a single comment about two distinct paragraphs in a text, and the role of each in the annotation is different: one is being compared to the other and it matters which is which. A hypothetical literature set of motivations is used to demonstrate the extensibility of the framework.

{
  "@context": ["http://www.w3.org/ns/anno.jsonld", "http://example.org/lit/context.json"],
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "body": {
    "role": "lit:comparing", 
    "content": { "text": "The first passage is a clear derivative of the second" }
  },
  "target": [{
      "role": "lit:antecedent",
      "content": "http://example.org/book1#para1"
    },
    {
      "role": "lit:subsequent",
      "content": "http://example.org/book1#para6"
    }
  ]
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasBody [
        oa:hasRole lit:comparing ;
        oa:hasSource [ oa:text "The first passage is a clear derivative of the second" ] ;
    oa:hasTarget [
        oa:hasRole lit:antedent ;
        oa:hasSelector [
          a oa:FragmentSelector ;
          rdf:value "para1" ] ;
        oa:hasSource  ],
      [
        oa:hasRole lit:subsequent ;
        oa:hasSelector [
          a oa:FragmentSelector ;
          rdf:value "para6" ] ;
        oa:hasSource  ]

Literal Bodies Cannot Have Roles

A simple literal body cannot have a role associated with it, in the same way that it cannot have a format, language, author, license or anything else. Instead, one of the above forms must be used.
{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.com/target1"},
  "body": "I like this"
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget  ;
    oa:hasBody "I like this" .

Multiplicity with Roles

The multiplicity constructs would also have the same pattern of being the resource associated with a SpecificResource that maintains the role.
{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.com/target1"},
  "body": {
    "role": "commenting",
    "content": {
      "type": "Choice",
      "members": [
        "http://example.org/comment-en",
        "http://example.org/comment-fr"
      ]
    }
  }
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget  ;
    oa:hasBody [
      oa:hasRole oa:commenting ;
      oa:hasSource [
        a oa:Choice ;
        oa:members (
          <http://example.org/comment-en>
          <http://example.org/comment-fr>
        )
      ]
    ]

Further Considerations

Require the use of SpecificResource for Bodies

A further proposal was to make the use of SpecificResource required for body when it was not a plain literal. Thus, there would be only two cases to deal with in JSON: the body is a string and treated as a plain text comment; the body is an object, which is a SpecificResource and may have either an EmbeddedContent or external resource as its source/content.

This change would make the following illegal:

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": {"id": "http://example.org/tag1"} 
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody <http://example.org/tag1> .
And instead require this construction:
{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": {"content": "http://example.org/tag1"} 
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody [ oa:hasSource <http://example.org/tag1> ]

Require the use of SpecificResource for Targets

If the Body MUST be a SpecificResource (or literal) and the argument in favor of this is that it's more consistent to always use the same pattern, then as targets may also be SpecificResources, the implication is that targets MUST be SpecificResources too. The use of selectors and states are more common with Targets than bodies, however roles would be significantly less common.

This change would make the following illegal:

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"id": "http://example.org/target1"},
  "body": {"id": "http://example.org/tag1"} 
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody <http://example.org/tag1> .
And instead require this construction:
{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"content": "http://example.org/target1"},
  "body": {"content": "http://example.org/tag1"} 
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget [ oa:hasSource <http://example.org/target1> ] ;
    oa:hasBody [ oa:hasSource <http://example.org/tag1> ]

Allow hasRole on new EmbeddedTextualBody class

An extended proposal would also allow hasRole to be included directly on an embedded textual body. This proposal is incompatible with the proposals to require SpecificResource for Body, Target, or both. Given the proposal to remove unnecessary types, this also makes the determination of the class of the body more difficult as there are multiple similar options.

At the ontology level, there would be a subClass of EmbeddedContent (which is used for embedding stylesheets, SVG content and potentially further representations) that would be used explicitly for this purpose. That class is not represented in the examples below, as it would not appear in the serialization.

Along with the SpecificResource construction needed for when the body has a URI, the proposal would also allow the following as a valid construction:
{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"content": "http://example.org/target1"},
  "body": {
    "role": "commenting",
    "text": "I love this"
  }
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget [ oa:hasSource <http://example.org/target1> ] ;
    oa:hasBody [ 
      oa:hasRole oa:commenting ;
      oa:text "I love this"
    ]

Rename hasSource to hasContent

Source is a somewhat arcane name and has no real relationship to the web architecture or anything else. If content is more intuitive as a key in JSON, then oa:hasContent would be more intuitive as a predicate in the ontology.

This change would make the following illegal. Note that it only affects the Turtle serialization:

<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget [ oa:hasSource <http://example.org/target1> ] ;
    oa:hasBody [ oa:hasSource <http://example.org/tag1> ]
And instead require this construction:
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget [ oa:hasContent <http://example.org/target1> ] ;
    oa:hasBody [ oa:hasContent <http://example.org/tag1> ]

Remove motivatedBy completely

Once per-body roles are taken up, especially if SpecificResource is required, then the motivation on the Annotation is only minimally useful in the model. It becomes a hint as to the purpose of the annotation as a whole, which clients are unlikely to know a priori, nor be able to have the user specify it as they would then need to understand the available motivations. Clients would be unlikely to take any action based on the annotation's motivation, and developers might be confused by differing motivations and roles.

Instead, with the ability to have a role on the target, the top contenders for annotation level motivations (bookmarking and highlighting, as they might have no body at all), would be roles on the Target SpecificResource, as above.

This change would make the following illegal:

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "motivation": "commenting",
  "target": {"id": "http://example.org/target1"},
  "body": {
    "content": {"text": "I love this"}
  }
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasMotivation oa:commenting ;
    oa:hasTarget <http://example.org/target1> ;
    oa:hasBody [
      oa:hasSource [ oa:text "I love this" ]
    ]
And instead require this construction:
{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"content": "http://example.org/target1"},
  "body": {
    "role": "commenting",
    "content": {"text": "I love this"}
  }
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget [ oa:hasSource <http://example.org/target1> ] ;
    oa:hasBody [ 
      oa:hasRole oa:commenting ;
      oa:hasSource [ oa:text "I love this" ]
    ]

Use motivation instead of role

Instead of using the role nomenclature, we could stick with using motivatedBy for Specific Resources rather than on the Annotation.

This would change the above examples to look like:

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/anno1",
  "type": "Annotation",
  "target": {"content": "http://example.org/target1"},
  "body": {
    "motivation": "commenting",
    "content": {"text": "I love this"}
  }
}
<http://example.org/anno1> a oa:Annotation ;
    oa:hasTarget [ oa:hasSource <http://example.org/target1> ] ;
    oa:hasBody [ 
      oa:motivatedBy oa:commenting ;
      oa:hasSource [ oa:text "I love this" ]
    ]