w3c/activitystreams

as:closed is wrongly defined in the normative context as only being xsd:datetime

trwnh opened this issue · 5 comments

trwnh commented

Please Indicate One:

  • Editorial
  • Question
  • Feedback
  • Blocking Issue
  • Non-Blocking Issue

Please Describe the Issue:

Per issue triage with @evanp just now, it was stated that Activity Vocabulary takes precedence over the context document for what is considered normative.

Per AS2-Vocab: https://www.w3.org/TR/activitystreams-vocabulary/#dfn-closed

Indicates that a question has been closed, and answers are no longer accepted.

Range: Object | Link | xsd:boolean | xsd:datetime

Per another issue regarding url in w3c/activitypub#375

url may be a Link node but it may also be xsd:anyURI (per AS2-Vocab range). I am not sure how this should be expressed in LD. An array is incorrect since it implies both. I don't know how to properly define "either-or" or "any of" types.

So this is an even more complex variant of that. closed can be:

  • a boolean false to indicate the Question is still open
  • a boolean true to indicate the Question is closed
  • a datetime xsd:datetime to indicate the date and/or time that the question was closed (implying true as above)
  • an Object or a Link that references what it was that actually closed the Question, i.e. the "accepted answer" (implying true as above)

A naive approach would be to use a @type array like so:

"closed": {
  "@id": "as:closed",
  "@type": "xsd:datetime"
}
"closed": {
  "@id": "as:closed",
  "@type": ["xsd:boolean", "xsd:datetime", "@id"]
}

But I'm not actually sure this means what you would think it means. We intend a "one-of" relation, but the above encodes an "all of the above" relation.

Possible solution

  • Define new terms for each of the types, similar to how items and orderedItems are defined?
    • So possibly a closedBy term that has @type: @id can handle the case of Object or Link. It should have the same @id of https://www.w3.org/ns/activitystreams#closed
    • But that still leaves ambiguity between booleans and datetimes. I suppose you could drop the @type entirely for closed?
trwnh commented

I believe the only type that "matters" is @id since this directly controls whether something is an @id or a @value, hence why I explored closedBy as a possible solution, and then dropping the xsd:datetime because this is more of a "hint" for any type checkers.

evanp commented

Dmitri will reach out to JSON-LD folks to find out if there's a way to encode these multiple types.

If not, we should probably keep "closed" as a datetime as currently defined in the context document, and consider recommending other existing properties like "result" as seen in the Vocabulary document in [Representing Questions)(https://www.w3.org/TR/activitystreams-vocabulary/#questions). This may rise to the level of an erratum, although it's not clear that this is not the author's or working group's intent.

We should also do a survey of existing usage to see if any software uses the other types besides datetime.

Defining a context term as both an object reference (@id) and a @value (if that's allowed) causes issues in modeling the associated vocabulary/ontology using OWL. In OWL, a property must be either an ObjectProperty or a DataProperty, but not both. This is already a problem for url ("@id" in the context, but Link | xsd:anyURI in the vocabulary). It would be nice to not expand that anti-pattern. Note that xsd:anyURI is a literal so it would be a @value in the context and a DataProperty in OWL.

EDIT: After doing more reading, I'm not completely sure about xsd:anyURI modeling in JSON-LD contexts. I see some information saying it could be either, depending on the "context" (sorry). I do know it caused issues when I was working on an OWL ontology for AS2. #440 is also somewhat related.

trwnh commented

If the expanded term definition contains the @type keyword, its value MUST be an IRI, a compact IRI, a term, null, or one of the keywords @id, @json, @none, or @vocab.

So this rules out the array type as an option.

Using the JSON-LD playground: https://json-ld.org/playground/#startTab=tab-compacted&json-ld=%5B%7B%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23closed%22%3A%5B%7B%22%40type%22%3A%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%23dateTime%22%2C%22%40value%22%3A%222023-09-01%22%7D%2C%7B%22%40id%22%3A%22https%3A%2F%2Fexample.com%2Fpr%2F13%22%7D%5D%7D%5D&context=%7B%22%40context%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%22%7D

Starting with this extended context:

{
  "@context": ["https://www.w3.org/ns/activitystreams", {
    "closedBy": {
      "@id": "https://www.w3.org/ns/activitystreams#closed",
      "@type": "@id"
    }
  }],
  "closed": "2023-09-01",
  "closedBy": "https://example.com/pr/1"
}

We see that this results in the unambiguous expanded form:

[
  {
    "https://www.w3.org/ns/activitystreams#closed": [
      {
        "@type": "http://www.w3.org/2001/XMLSchema#dateTime",
        "@value": "2023-09-01"
      },
      {
        "@id": "https://example.com/pr/1"
      }
    ]
  }
]

And this compacts against AS2's context into this:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "closed": "2023-09-01",
  "as:closed": {
    "id": "https://example.com/pr/1"
  }
}

So I think the correct solution to this is, from an LD perspective:

  • Add a term closedBy which has @type: @id to the normative context
  • Either:
    • amend/errata such that xsd:boolean is no longer in the range of closed
    • remove @type: xsd:datetime from closed in order to support boolean values.
      • (This might break old documents which encode xsd:datetime and were stored as expanded form, but this is a theoretical corner case since I assume most implementations store documents roughly in compacted form or some database format that can be used to construct the compacted form.)

The addition of closedBy should not be problematic unless implementations already used node objects for closed, but this is honestly more of a bug that should be fixed because it would currently not be consistent with the compacted form, and there isn't actually a way to be consistent with the compacted form without defining such a term for @type: @id use cases. The compaction would see the id-node as invalid and the property would be changed from closed to as:closed, as seen in this playground example: https://json-ld.org/playground/#startTab=tab-compacted&json-ld=%5B%7B%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23closed%22%3A%5B%7B%22%40id%22%3A%22https%3A%2F%2Fexample.com%2Fpr%2F1%22%7D%5D%7D%5D&context=%7B%22%40context%22%3A%5B%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%22%5D%7D

I don't think this is a good candidate for a FEP because there is a clear error in the normative AS2 context compared to the spec, and I think it should be fixed. Terms should be @id or @value but not both, as @steve-bate points out. This is a quirk of JSON-LD in much the same way that orderedItems is a term that has the same @id as items, i.e. https://www.w3.org/ns/activitystreams#items, but the former term is defined with @container: @list and the latter term is not. The Activity Vocabulary spec page doesn't actually define orderedItems as a property, and it is used only in JSON-LD examples.