w3c / activitypub

http://w3c.github.io/activitypub/
Other
1.2k stars 77 forks source link

Revisit the `https://www.w3.org/ns/activitystreams#Public` == `as:Public` == `Public` equivalence and guidance #404

Open trwnh opened 8 months ago

trwnh commented 8 months ago

Motivation

Continuing from #264 and with this JSON-LD playground link, we make the following observations:

  1. First, that the AS2-Core spec requires that AS2 documents are consistent with the JSON-LD compacted form;
  2. Second, that within the playground we observe that the full IRI always gets compacted as as:Public and never as Public;
  3. Third, that Public actually does not expand to the full IRI in any circumstance!

We further observe, from the JSON-LD spec:

  1. Fourth, that per JSON-LD 1.1 Section 3.2 "IRIs" Note 2, a term definition only has an effect when encountered within @type or as a property name, or "elsewhere that a string is interpreted as a vocabulary item". So the "Public": "as:Public" term definition has no current effect.
  2. Fifth, that per JSON-LD 1.1 Section 4.2.3 "Type Coercion", there are two ways to interpret a string value as an IRI -- @type: @id or @type: @vocab. The former (ID value) will only process IRIs, i.e. it will only process when a colon is present. The latter (Vocab value) will first try to interpret the string as a term. Thus, we can override the behavior observed in observation 4, provided that we use @type: @vocab. (See next comment for more exploration.)

Relevant quotes

1.4 Terminology:

A relative IRI reference is an IRI reference that is relative to some other IRI, typically the base IRI of the document. Note that properties, values of @type, and values of terms defined to be vocabulary relative are resolved relative to the vocabulary mapping, not the base IRI.

A term definition is an entry in a context, where the key defines a term which may be used within a map as a key, type, or elsewhere that a string is interpreted as a vocabulary item.

3.2 IRIs:

Properties, values of @type, and values of properties with a term definition that defines them as being relative to the vocabulary mapping, may have the form of a relative IRI reference, but are resolved using the vocabulary mapping, and not the base IRI.

An IRI is generated for the string value of any key for which there are coercion rules that contain an @type key that is set to a value of @id or @vocab.

4.2.3 Type Coercion:

Type coercion is specified within an expanded term definition using the @type key. The value of this key expands to an IRI. Alternatively, the keyword @id or @vocab may be used as value to indicate that within the body of a JSON-LD document, a string value of a term coerced to @id or @vocab is to be interpreted as an IRI. The difference between @id and @vocab is how values are expanded to IRIs. @vocab first tries to expand the value by interpreting it as term. If no matching term is found in the active context, it tries to expand it as an IRI or a compact IRI if there's a colon in the value; otherwise, it will expand the value using the active context's vocabulary mapping, if present. Values coerced to @id in contrast are expanded as an IRI or a compact IRI if a colon is present; otherwise, they are interpreted as relative IRI references.

Pitch

In summary, the logical conclusion is as follows: Pick one of the following.

Make no changes; use as:Public

Per the 1st and 2nd observations, we make no changes but instead make the following guidance:

Implementations MUST use as:Public in order to be consistent with the compacted form; however, they SHOULD treat https://www.w3.org/ns/activitystreams#Public and Public as equivalent for compatibility with existing applications (and these uses should be phased out or dispreferred)

Per the 3rd and 4th observation, the term definition for Public => as:Public can be removed.

Change to @type: @vocab; use Public

Per the 5th observation, we can change the @type of to, cc, audience, bto, bcc from @type: @id to @type: @vocab. This would result in the Public term definition actually taking effect. Hence:

Implementations MUST use Public in order to be consistent with the compacted form; however, they SHOULD treat https://www.w3.org/ns/activitystreams#Public and as:Public as equivalent for compatibility with existing applications (and these uses should be phased out or dispreferred)

Make a normative change; use https://www.w3.org/ns/activitystreams#Public

This is more of a breaking change, and as explained above, unfavourable. In order to ensure consistency with the compacted form, it requires dropping the as term definition / prefix entirely, and rewriting the context document to stop using compact IRIs in all @id definitions. This would result in https://www.w3.org/ns/activitystreams#Public being the only valid representation. Hence:

Implementations MUST use https://www.w3.org/ns/activitystreams#Public; however, they SHOULD treat Public and as:Public as equivalent for compatibility with existing applications (and these uses should be phased out or dispreferred)

trwnh commented 8 months ago

For anyone curious, here's what it would take for the inclusion of Public to actually make sense:

Such an example is here:

https://json-ld.org/playground/#startTab=tab-compacted&copyContext=true&json-ld=%7B%22%40context%22%3A%5B%7B%22%40base%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%2F%22%2C%22Public%22%3A%7B%22%40id%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%2FPublic%22%7D%2C%22to%22%3A%7B%22%40id%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%2Fto%22%2C%22%40type%22%3A%22%40id%22%7D%2C%22cc%22%3A%7B%22%40id%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%2Fcc%22%2C%22%40type%22%3A%22%40id%22%7D%2C%22audience%22%3A%7B%22%40id%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%2Faudience%22%2C%22%40type%22%3A%22%40id%22%7D%7D%5D%2C%22to%22%3A%22Public%22%2C%22audience%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%2FPublic%22%7D

Obviously, this is completely untenable and would break a ton of things, as well as making all @id values potentially relative to this @base. So there's no way to get Public to "work right". It has to be as:Public (or, if the prefix were removed, https://www.w3.org/ns/activitystreams#Public)

EDIT: Apparently it can be done with @type: @vocab!

https://json-ld.org/playground/#startTab=tab-expanded&copyContext=true&json-ld=%7B%22%40context%22%3A%5B%7B%22as%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23%22%2C%22Public%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Public%22%2C%22to%22%3A%7B%22%40id%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23to%22%2C%22%40type%22%3A%22%40vocab%22%7D%2C%22cc%22%3A%7B%22%40id%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23cc%22%2C%22%40type%22%3A%22%40vocab%22%7D%2C%22audience%22%3A%7B%22%40id%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23audience%22%2C%22%40type%22%3A%22%40vocab%22%7D%7D%5D%2C%22to%22%3A%5B%22Public%22%2C%22https%3A%2F%2Fexample.com%2F1%22%5D%2C%22cc%22%3A%5B%22as%3APublic%22%2C%22https%3A%2F%2Fexample.com%2F2%22%5D%2C%22audience%22%3A%5B%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Public%22%2C%22https%3A%2F%2Fexample.com%2F3%22%5D%7D

JSON-LD 1.1 Section 4.2.3 "Type Coercion" describes this in further detail: https://www.w3.org/TR/json-ld11/#type-coercion

Examples 65 and 66 show this in further detail.

In order to make use of this, the context document needs to change to, cc, audience (and bto and bcc?) from @type: @id to @type: @vocab. As explained in the above section, @type: @vocab is like @type: @id but it does term expansion first (whereas @type: @id will expand against @base instead)

Example doc:

{
  "@context": [
    {
      "as": "https://www.w3.org/ns/activitystreams#",
      "Public": "https://www.w3.org/ns/activitystreams#Public",
      "to": {
        "@id": "https://www.w3.org/ns/activitystreams#to",
        "@type": "@vocab"
      },
      "cc": {
        "@id": "https://www.w3.org/ns/activitystreams#cc",
        "@type": "@vocab"
      },
      "audience": {
        "@id": "https://www.w3.org/ns/activitystreams#audience",
        "@type": "@vocab"
      }
    }
  ],
  "to": [
    "Public",
    "https://example.com/1"
  ],
  "cc": [
    "as:Public",
    "https://example.com/2"
  ],
  "audience": [
    "https://www.w3.org/ns/activitystreams#Public",
    "https://example.com/3"
  ]
}

Expands to:

[
  {
    "https://www.w3.org/ns/activitystreams#audience": [
      {
        "@id": "https://www.w3.org/ns/activitystreams#Public"
      },
      {
        "@id": "https://example.com/3"
      }
    ],
    "https://www.w3.org/ns/activitystreams#cc": [
      {
        "@id": "https://www.w3.org/ns/activitystreams#Public"
      },
      {
        "@id": "https://example.com/2"
      }
    ],
    "https://www.w3.org/ns/activitystreams#to": [
      {
        "@id": "https://www.w3.org/ns/activitystreams#Public"
      },
      {
        "@id": "https://example.com/1"
      }
    ]
  }
]

Compacts to:

{
  "@context": {
    "as": "https://www.w3.org/ns/activitystreams#",
    "Public": "https://www.w3.org/ns/activitystreams#Public",
    "to": {
      "@id": "https://www.w3.org/ns/activitystreams#to",
      "@type": "@vocab"
    },
    "cc": {
      "@id": "https://www.w3.org/ns/activitystreams#cc",
      "@type": "@vocab"
    },
    "audience": {
      "@id": "https://www.w3.org/ns/activitystreams#audience",
      "@type": "@vocab"
    }
  },
  "audience": [
    "Public",
    "https://example.com/3"
  ],
  "cc": [
    "Public",
    "https://example.com/2"
  ],
  "to": [
    "Public",
    "https://example.com/1"
  ]
}
ap-socialhub commented 8 months ago

This issue has been mentioned on SocialHub. There might be relevant details there:

https://socialhub.activitypub.rocks/t/fep-7502-limiting-visibility-to-authenticated-actors/3784/2

TallTed commented 8 months ago

@nightpool — Please edit your https://github.com/w3c/activitypub/issues/404#issuecomment-1868226523 and codefence every instance of any @word (single backticks will do, a la `@context`), including those in quoteblocks, such that every comment made here does not ping those GitHub users who did not choose to participate in this discussion.

trwnh commented 8 months ago

One thing I am not entirely clear on wrt @type: @vocab is whether it makes sense to close the door entirely on addressing IRIs relative to the @base. For example there is the possibility of doing something like

@context: [
  activitystreams, {
    @base: https://example.com/
  }]
to: [users/1, users/2]

or doing something like

GET https://example.com/actor

@context: activitystreams
inbox: inbox  # expands to https://example.com/actor/inbox
outbox: outbox  # expands to https://example.com/actor/outbox

My immediate take is that these relative IRI references should probably be avoided, even though they are valid. But in order to keep the possibility open, one would have to go with the "do nothing, use as:Public" option (and keep the coercion as @type: @id)

nightpool commented 8 months ago

My understanding is that relative URIs / base URI are explicitly disallowed by either as2 or AP, I seem to remember some language somewhere about it

On Wed, Dec 27, 2023, 1:21 PM a @.***> wrote:

One thing I am not entirely clear on wrt @type: @vocab is whether it makes sense to close the door entirely on addressing IRIs relative to the @base. For example there is the possibility of doing something like

@context: [ activitystreams, { @base: https://example.com/ }] to: [users/1, users/2]

or doing something like

GET https://example.com/actor

@context: activitystreams inbox: inbox # expands to https://example.com/actor/inbox outbox: outbox # expands to https://example.com/actor/outbox

My immediate take is that these relative IRI references should probably be avoided, even though they are valid. But in order to keep the possibility open, one would have to go with the "do nothing, use as:Public" option (and keep the coercion as @type: @id)

— Reply to this email directly, view it on GitHub https://github.com/w3c/activitypub/issues/404#issuecomment-1870567257, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABZCV7BQQ27SGZ6FHFT7TLYLRYLTAVCNFSM6AAAAABA4SP6SGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZQGU3DOMRVG4 . You are receiving this because you were mentioned.Message ID: @.***>

TallTed commented 8 months ago

@nightpool — Please edit your new https://github.com/w3c/activitypub/issues/404#issuecomment-1870568682 and delete the quoted email content, which includes a number of @name, which cannot be codefenced because GitHub doesn't handle Markdown in emailed comments. Sorry to keep banging on this drum, but it's the only way to prevent pinging those uninvolved GitHub users.

nightpool commented 8 months ago

Hi Ted,

Sorry, but I cannot edit my email message at this time. I'm sure that whoever has the GitHub username "id" is used to getting these sorts of mentions at this point and has them configured appropriately.

On Wed, Dec 27, 2023, 1:32 PM Ted Thibodeau Jr @.***> wrote:

@nightpool https://github.com/nightpool — Please edit your new #404 (comment) https://github.com/w3c/activitypub/issues/404#issuecomment-1870568682 and delete the quoted email content, which includes a number of name, which cannot be codefenced because GitHub doesn't handle Markdown in emailed comments. Sorry to keep banging on this drum, but it's the only way to prevent pinging those uninvolved GitHub users.

— Reply to this email directly, view it on GitHub https://github.com/w3c/activitypub/issues/404#issuecomment-1870574258, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABZCV5KZGHHZVXSFNGUJC3YLRZV3AVCNFSM6AAAAABA4SP6SGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZQGU3TIMRVHA . You are receiving this because you were mentioned.Message ID: @.***>

trwnh commented 8 months ago

2.2 of as2-core says

Relative IRI (and URL) references SHOULD NOT be used within an Activity Streams 2.0 document due to the fact that many JSON parser implementations are not capable of reliably preserving the base context necessary to properly resolve relative references.

so that's a SHOULD NOT, not a MUST NOT, but good catch anyway! still worth keeping in mind that type:vocab makes things relative to the vocab mapping and not the base mapping.

TallTed commented 5 months ago

"expected" language is good for non-normative discussion (primer or the like), instead of "should" or "must" that are often read as normative even in non-normative documents (or non-normative sections of normative documents) and even when lowercase

evanp commented 5 months ago

I think the best steps for us right now are as follows:

  1. A Primer page that lays out the guidance in option 1 -- that publishers ought to use as:Public for maximum interop, and that consumers ought to expect all three options.

  2. We consider the normative change of adding @type: @vocab to the AS2 context document once a new working group is called. We can mark this issue as "Next version" so we remember to consider it at that time (even if it's closed).

  3. Review the AS2 and AP specs for examples that use Public or the https://www.w3.org/ns/activitystreams#Public and consider making ERRATA for those examples, since they are technically not compliant since they aren't equivalent to the compacted form.