mirror of
https://codeberg.org/fediverse/fep.git
synced 2026-08-08 13:35:51 +00:00
7888: use simpler examples and clarify extension points (#523)
clarifications made: - the `rdfs:label` of `as:context` is roughly "was created in relation to", citing James Snell in a github issue explaining the intended usage of the `context` property. - most usages of the concept of a "context" include behavior where deleting a context deletes anything within that context. this is not a requirement or recommendation, but it is called out as possible behavior. - exactly how to participate in a context or copy an existing context is protocol-dependent and left out-of-scope of this FEP; to be followed up on in future FEP efforts - examples are simplified to leave out protocol details and focus on publishing and consuming context. a new example 4 is added for demonstrating the extension point for "canonical collections". Reviewed-on: https://codeberg.org/fediverse/fep/pulls/523 Co-authored-by: a <a@trwnh.com> Co-committed-by: a <a@trwnh.com>
This commit is contained in:
+131
-259
@@ -20,9 +20,10 @@ See "Appendix A: Rationale" for fuller analysis of the definition, as well as us
|
||||
|
||||
In short:
|
||||
|
||||
- It is possible for objects to exist within implicit contexts. For example, you might group all objects sharing a certain `tag`, or all objects having a common `audience`.
|
||||
- It is possible for objects to exist within implicit contexts. For example, you might group all objects sharing a certain property value. Properties like `context`, `audience` and `tag` can be used for similar purposes.
|
||||
- `context` roughly corresponds to the label "was created in relation to". Compare to `audience`, which roughly corresponds to the label "is considered relevant to". Compare also to `tag`, which roughly corresponds to the label "is associated with a topic of".
|
||||
- An explicit `context` embodies *purpose*. Things grouped by the same `context` "belong together" in a way that can't be said about things grouped by the same `tag`.
|
||||
- Objects with a `context` exist *within* that context, and are meant to be seen and interpreted *in context of* something else. In most cases, you do not want to view the object on its own; it should be viewed together with other objects, contextually.
|
||||
- Objects with a `context` exist *within* that context, and are meant to be seen and interpreted *in context of* something else. In most cases, you do not want to view the object on its own; it should be viewed together with other objects, contextually. Deleting a context might reasonably delete or garbage-collect objects within that context.
|
||||
- You might use `context` to represent a "thread", "topic", "conversation", "room", "channel", "forum", "wall", "guild", "space", "project", or so on.
|
||||
|
||||
The requirements below can be summarized like so:
|
||||
@@ -40,7 +41,7 @@ When generating an object with a `context` as a publisher:
|
||||
|
||||
### Purpose
|
||||
|
||||
A `context` SHOULD have a purpose; consider `tag` for looser references. Objects sharing a certain `context` SHOULD be strongly related and intended to be viewed in the same grouping.
|
||||
A `context` SHOULD have a purpose; consider `tag` for looser references. Objects sharing a certain `context` SHOULD be strongly related and intended to be viewed in the same grouping. Deleting the `context` MAY delete all objects within that context.
|
||||
|
||||
### Dereferencing and resolving
|
||||
|
||||
@@ -81,7 +82,7 @@ When encountering an object with a `context` and choosing to author your own obj
|
||||
- You MAY set your own `context`, if you wish for your object to exist in a different context.
|
||||
- You MAY remove the `context` entirely, if you wish for your object to exist on its own.
|
||||
|
||||
Note that `context` can be present on either the object, the activity, or both. It is also possible for different `context` references to be placed on each. This depends on how `context` is used. In the case of an activity wrapping an object with context, if the activity is deemed to exist in the same context as the object, then you SHOULD use the same `context` reference on both the object and also on its wrapping activity.
|
||||
Note that `context` can be present on either the object, the activity, or both. It is also possible for different `context` references to be placed on each. This depends on how `context` is used within a given protocol. Protocol considerations for when to use certain contexts are out-of-scope for this FEP. Protocol considerations for how to negotiate participation in someone else's context are also out-of-scope for this FEP.
|
||||
|
||||
### Keeping relevant entities in the loop
|
||||
|
||||
@@ -111,6 +112,46 @@ From the current definition in [VOCAB]: https://www.w3.org/TR/activitystreams-vo
|
||||
|
||||
Aside from being "intentionally vague", the definition is also somewhat circular; it requires knowing what a context is and having some conceptual understanding of the notion of "context". However, we are given some guidance towards its "intended function", which is to group objects by some common purpose or origin.
|
||||
|
||||
#### Supporting statements from spec authors
|
||||
|
||||
In a [GitHub issue][GH300] from ActivityStreams 2.0's development cycle, James Snell provides the following example:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "Note",
|
||||
"content": "This is a note",
|
||||
"scope": {
|
||||
"type": "Organization",
|
||||
"name": "My Employer"
|
||||
},
|
||||
"to": ["john@example.com", "sally@example.com"],
|
||||
"context": {
|
||||
"type": "http://example.org/types/Project",
|
||||
"name": "A Project"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
James Snell then comments that:
|
||||
|
||||
> - The `scope` indicates that the audience for the note is only members of the Organization.
|
||||
> - The `to` indicates specific people who should be actively notified.
|
||||
> - The `context` indicates a larger context within which the note exists.
|
||||
|
||||
James Snell then clarifies (emphasis added):
|
||||
|
||||
> `scope` is not access control [...] a consuming implementation may include the note on the activity timeline of anyone associated with the "My Employer" organization, but it would only notify two individuals listed by the `to` property. **The `context` property**, on the other hand, has absolutely nothing to do with audience targeting. The above note **is essentially saying, "This is a note that was created in relation to `A Project`**. Make the note available to anyone in the `My Employer` organization but specifically notify John and Sally"
|
||||
|
||||
Therefore, we can establish that `context` as a property roughly translates to a label of "was created in relation to".
|
||||
|
||||
In [a separate issue][GH238], James Snell provides another explanation:
|
||||
|
||||
> The context is really intended to allow objects and activities to be **logically grouped**. For instance, in an enterprise setting, the context may group activities by project while the scope would identify one or more teams for which the activity is considered relevant, while the to/cc fields are used to indicate specific individuals to notify.
|
||||
|
||||
`scope` was later renamed to `audience`, but the two properties remain closely related and are presented together in [AS2-VOCAB Section 5.1.1 "Audience and Context"][AUDIENCE-AND-CONTEXT]:
|
||||
|
||||
> Activities are rarely isolated events. Often, multiple individual activities will be performed around a similar context or audience. For instance, a collaborators working on a shared project might perform multiple related activities in the process of achieving some goal. Such activities can be logically grouped together using the context property, and scoped to a particular audience using the audience property.
|
||||
|
||||
### Purpose and intent; or, why not use a tag?
|
||||
|
||||
We might similarly use a `tag` for grouping objects and activities. Several fediverse projects often include a `Hashtag` (defined as an extension within the ActivityStreams namespace, but not actually adopted or defined formally). This `Hashtag` signals an intent to be included or discovered through a collection of objects bearing the same `Hashtag`, uniquely identified by its `name`. The maintenance of such implicit collections is assumed to be the responsibility of the receiving server, although an `href` might be provided for convenience, in order to browse the implicit collection of tagged objects as seen from that origin server. (This also makes the `Hashtag` a sub-type of `Link`.)
|
||||
@@ -144,11 +185,11 @@ Contexts may be associated with other contexts:
|
||||
- A "wall" on a social networking profile may contain conversations, which in turn contain the posts/comments
|
||||
- A "guild" or "space" may contain multiple chat rooms with a common audience
|
||||
|
||||
It is also possible to *not* have a context. Such objects exist only in the general context of their author (via `attributedTo`) or other implicit contexts, and are otherwise self-sufficient. This can include:
|
||||
It is also possible to *not* have a context. Such objects exist only in the general context of their author (via `attributedTo`) or other implicit contexts, and are otherwise self-sufficient.
|
||||
|
||||
- An article published on a web site, particularly one meant to be accessible directly via a permalink
|
||||
- A post in a blogging or microblogging environment, particularly one that does not represent a conversation, or where `inReplyTo` is meant only as a loose reference.
|
||||
- An activity intended for or acting upon an object without a context
|
||||
Considerations on when to use context include:
|
||||
|
||||
- If deleting a context, then objects within that context might reasonably be deleted or garbage-collected since they have lost their purpose.
|
||||
|
||||
---
|
||||
|
||||
@@ -156,7 +197,9 @@ It is also possible to *not* have a context. Such objects exist only in the gene
|
||||
|
||||
(This section is non-normative.)
|
||||
|
||||
### Example 1: A minimal example for participating in a context
|
||||
### Example 1: A minimal example for grouping objects by context
|
||||
|
||||
This example demonstrates how objects sharing the same context can be logically grouped together.
|
||||
|
||||
You encounter the following object:
|
||||
|
||||
@@ -165,99 +208,52 @@ You encounter the following object:
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-object",
|
||||
"context": "https://domain.example/some-context",
|
||||
"content": "Hello world",
|
||||
"summary": "<some-object> exists in <some-context> and has content saying \"Hello world\"."
|
||||
"summary": "<some-object> exists in <some-context>."
|
||||
}
|
||||
```
|
||||
|
||||
You wish to participate in the context, so you dereference the context:
|
||||
You wish to participate in the same context, so you dereference the context in order to learn more about it:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-context",
|
||||
"attributedTo": "https://domain.example/context-owner",
|
||||
"audience": "https://domain.example/context-audience",
|
||||
"type": "https://extension.example/SomeType",
|
||||
"https://extension.example/someProperty": {
|
||||
"id": "https://domain.example/some-context/collection",
|
||||
"type": "OrderedCollection",
|
||||
"orderedItems": ["https://domain.example/some-object"],
|
||||
},
|
||||
"summary": "<some-context> is a context owned by <context-owner> and with an audience of <context-audience>. It has a canonical collection <some-context/collection> which currently contains <some-object>."
|
||||
"summary": "<some-context> is owned by <context-owner>."
|
||||
}
|
||||
```
|
||||
|
||||
You send your activity to the context authority, while copying their context:
|
||||
You create an object, while copying that context onto your object:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/your-activity",
|
||||
"actor": "https://domain.example/you",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"id": "https://domain.example/your-object",
|
||||
"context": "https://domain.example/some-context",
|
||||
"content": "Hello!"
|
||||
},
|
||||
"audience": ["https://domain.example/context-owner", "https://domain.example/context-audience"],
|
||||
"summary": "<you> Created <your-object> in <some-context>, and are delivering this activity addressing <context-owner> and <context-audience>."
|
||||
"id": "https://domain.example/your-object",
|
||||
"context": "https://domain.example/some-context",
|
||||
"summary": "<your-object> exists in <some-context> as well."
|
||||
}
|
||||
```
|
||||
|
||||
The context authority then might forward this activity to the context audience.
|
||||
|
||||
The context authority also might add your object or message to the context's canonical collection:
|
||||
Distribution occurs somehow; you may want to notify the `<context-owner>` or seek their acknowledgement of your object, but these things are out-of-scope of this example. A graph source or dataset containing these two objects may be queried for objects sharing the same context:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/their-activity",
|
||||
"actor": "https://domain.example/context-owner",
|
||||
"type": "Add",
|
||||
"object": "https://domain.example/your-object",
|
||||
"target": "https://domain.example/some-context/collection",
|
||||
"audience": [
|
||||
"https://domain.example/context-owner-followers",
|
||||
"https://domain.example/context-audience",
|
||||
"https://domain.example/you", // to keep you in the loop
|
||||
"https://domain.example/your-followers" // for inbox forwarding
|
||||
],
|
||||
"summary": "The <context-owner> Added <your-object> to <some-context/collection>, and they are delivering this activity addressing their followers, the <context-audience>, <you>, and <your-followers>."
|
||||
"id": "https://domain.example/results-for-your-query",
|
||||
"type": "Collection",
|
||||
"summary": "The <results-for-your-query> show that 2 items have a context of <some-context>. They are <some-object> and <your-object>.",
|
||||
"totalItems": 2,
|
||||
"items": [
|
||||
"https://domain.example/some-object",
|
||||
"https://domain.example/your-object"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The resulting state of the context's canonical collection is now like so:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-context",
|
||||
"attributedTo": "https://domain.example/context-owner",
|
||||
"audience": "https://domain.example/context-audience",
|
||||
"type": "https://extension.example/SomeType",
|
||||
"https://extension.example/someProperty": {
|
||||
"id": "https://domain.example/some-context/collection",
|
||||
"type": "OrderedCollection",
|
||||
"orderedItems": [
|
||||
"https://domain.example/some-object",
|
||||
"https://domain.example/your-object"
|
||||
],
|
||||
},
|
||||
"summary": "<some-context/collection> now contains <some-object> and <your-object> after the latter has been Added to the OrderedCollection by <context-owner>."
|
||||
}
|
||||
```
|
||||
|
||||
Third-party observers (such as members of `https://domain.example/context-audience`) can validate or identify the Add activity as modifying a canonical collection by using the following checks:
|
||||
|
||||
- `Add.actor` == `target.attributedTo` (the actor is allowed to modify a collection that they own)
|
||||
- `target` == `object.context` (the object is being added into its declared context)
|
||||
|
||||
Alternatively, observers can use the Add as a signal to invalidate their cache of the canonical collection and refetch it.
|
||||
|
||||
### Example 2: Choosing not to participate in the same context
|
||||
|
||||
This example demonstrates how objects can have different contexts, indicating that they were created for different purposes. Though they may be grouped by other criteria, they do not share a primary reason for existing.
|
||||
|
||||
You encounter the following object:
|
||||
|
||||
```json
|
||||
@@ -265,126 +261,53 @@ You encounter the following object:
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-object",
|
||||
"context": "https://domain.example/some-context",
|
||||
"content": "Hello world",
|
||||
"summary": "<some-object> exists in <some-context> and has content saying \"Hello world\"."
|
||||
"summary": "<some-object> exists in <some-context>."
|
||||
}
|
||||
```
|
||||
|
||||
You want to establish your own context, separately from the current object's context, so you create a canonical collection to be referenced from a context object, then create that context object. This results in two activities:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/creating-a-context-collection",
|
||||
"actor": "https://domain.example/you",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"id": "https://domain.example/a-different-context/collection",
|
||||
"type": "OrderedCollection",
|
||||
"attributedTo": "https://domain.example/you"
|
||||
},
|
||||
"summary": "<you> Created <a-different-context/collection>, which is an OrderedCollection."
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/creating-a-different-context",
|
||||
"actor": "https://domain.example/you",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"id": "https://domain.example/a-different-context",
|
||||
"type": "https://extension.example/SomeType",
|
||||
"https://extension.example/someProperty": "https://domain.example/a-different-context/collection",
|
||||
"attributedTo": "https://domain.example/you"
|
||||
},
|
||||
"summary": "<you> Created <a-different-context>, which is SomeType and has an associated OrderedCollection via someProperty."
|
||||
}
|
||||
```
|
||||
|
||||
You can now set this new context on your interaction, with the intent that your interaction is shown in a separate grouping from the original object:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/creating-a-post-in-a-different-context",
|
||||
"actor": "https://domain.example/you",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"id": "https://domain.example/a-post-in-a-different-context",
|
||||
"content": "Starting a new thread to say \"Hello World\" in a different context.",
|
||||
"inReplyTo": {
|
||||
"id": "https://domain.example/some-object",
|
||||
"context": "https://domain.example/some-context",
|
||||
"content": "Hello world",
|
||||
"summary": "<some-object> exists in <some-context> and has content saying \"Hello world\"."
|
||||
},
|
||||
"context": "https://domain.example/a-different-context"
|
||||
},
|
||||
"summary": "<you> Created <a-post-in-a-different-context> which is inReplyTo <some-object> in <some-context>, but your object is in <a-different-context>."
|
||||
}
|
||||
```
|
||||
|
||||
You add your object to your own context's canonical collection:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/their-activity",
|
||||
"actor": "https://domain.example/you",
|
||||
"type": "Add",
|
||||
"object": "https://domain.example/a-post-in-a-different-context",
|
||||
"target": "https://domain.example/a-different-context/collection",
|
||||
"summary": "<you> Added <a-post-in-a-different-context> to <a-different-context/collection>."
|
||||
}
|
||||
```
|
||||
|
||||
The original object's context is unchanged:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-context",
|
||||
"attributedTo": "https://domain.example/context-owner",
|
||||
"audience": "https://domain.example/context-audience",
|
||||
"type": "https://extension.example/SomeType",
|
||||
"https://extension.example/someProperty": {
|
||||
"id": "https://domain.example/some-context/collection",
|
||||
"type": "OrderedCollection",
|
||||
"orderedItems": ["https://domain.example/some-object"],
|
||||
},
|
||||
"summary": "<some-context> is a context owned by <context-owner> and with an audience of <context-audience>. It has a canonical collection <some-context/collection> which currently contains <some-object>."
|
||||
}
|
||||
```
|
||||
|
||||
Your context now looks like this:
|
||||
You want to establish your own context, separately from the current object's context:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/a-different-context",
|
||||
"attributedTo": "https://domain.example/you",
|
||||
"audience": "https://domain.example/some-audience",
|
||||
"type": "https://extension.example/SomeType",
|
||||
"https://extension.example/someProperty": {
|
||||
"id": "https://domain.example/a-different-context/collection",
|
||||
"type": "OrderedCollection",
|
||||
"orderedItems": ["https://domain.example/a-post-in-a-different-context"],
|
||||
},
|
||||
"summary": "<a-different-context> is a context owned by <you> and with an audience of <some-audience>. It has a canonical collection <a-different-context/collection> which currently contains <a-post-in-a-different-context>."
|
||||
"summary": "<a-different-context> is owned by <you>."
|
||||
}
|
||||
```
|
||||
|
||||
You may declare that your object is in some way a response to the object that you encountered, but because the contexts are the same, they do not share a primary grouping:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/your-object",
|
||||
"inReplyTo": {
|
||||
"id": "https://domain.example/some-object",
|
||||
"context": "https://domain.example/some-context",
|
||||
"summary": "<some-object> exists in <some-context>."
|
||||
},
|
||||
"context": "https://domain.example/a-different-context",
|
||||
"summary": "<your-object> is a response to <some-object>, but <some-object> exists in <some-context> while <your-object> exists in <a-different-context>."
|
||||
}
|
||||
```
|
||||
|
||||
Querying replies for the original object might surface your object, but querying the context for the original object will not surface your object.
|
||||
|
||||
Later, `<some-context>` is deleted. In some cases, `<some-object>` might be garbage-collected, since it has lost its reason or purpose for existing; at best, it is considered orphaned. However, `<your-object>` continues to exist because it was created in `<a-different-context>` which still exists.
|
||||
|
||||
### Example 3: Encountering multiple contexts
|
||||
|
||||
This example demonstrates how one might deal with objects that have multiple contexts.
|
||||
|
||||
You encounter an object with multiple contexts:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-object",
|
||||
"context": ["https://domain.example/some-context", "https://domain.example/some-other-context"]
|
||||
"content": "Hello world",
|
||||
"summary": "<some-object> exists in <some-context> and <some-other-context> and has content saying \"Hello world\"."
|
||||
"context": ["https://domain.example/some-context", "https://domain.example/some-other-context"],
|
||||
"summary": "<some-object> exists in <some-context> and <some-other-context>."
|
||||
}
|
||||
```
|
||||
|
||||
@@ -395,9 +318,7 @@ You dereference the two contexts:
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-context",
|
||||
"attributedTo": "https://domain.example/context-owner",
|
||||
"type": "Object",
|
||||
"summary": "<some-context> is an Object owned by <context-owner>.",
|
||||
"https://extension.example/someProperty": "https://domain.example/some-context/collection"
|
||||
"summary": "<some-context> is owned by <context-owner>."
|
||||
}
|
||||
```
|
||||
|
||||
@@ -407,104 +328,52 @@ You dereference the two contexts:
|
||||
"id": "https://domain.example/some-other-context",
|
||||
"attributedTo": "https://domain.example/other-context-owner",
|
||||
"type": "Object",
|
||||
"summary": "<some-other-context> is an Object owned by <other-context-owner>.",
|
||||
"https://extension.example/someProperty": "https://domain.example/some-other-context/collection"
|
||||
"summary": "<some-other-context> is owned by <other-context-owner>."
|
||||
}
|
||||
```
|
||||
|
||||
You can now choose to participate in either context, both contexts, a different context, or no context.
|
||||
As a third-party observer, you can choose to browse either context.
|
||||
|
||||
To participate in both contexts:
|
||||
As a third-party interactor, you can choose to declare an object in either context, both contexts, a different context, or no context.
|
||||
|
||||
The protocol considerations for which contexts are considered valid or acceptable are out-of-scope of this FEP, but dereferencing the contexts can provide more information that can help you make this choice. Perhaps you expect a certain type to be declared, or perhaps you require an owner, or perhaps some other criteria is enforced.
|
||||
|
||||
### Example 4: Publishing, consuming, and interacting with authoritative contexts that have canonical collections
|
||||
|
||||
This example demonstrates how one might expose all objects acknowledged by a context owner to exist within the context.
|
||||
|
||||
You encounter the following object:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/your-activity",
|
||||
"actor": "https://domain.example/you",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"id": "https://domain.example/your-object",
|
||||
"context": ["https://domain.example/some-context", "https://domain.example/some-other-context"],
|
||||
"content": "Hello!"
|
||||
},
|
||||
"audience": ["https://domain.example/context-owner", "https://domain.example/other-context-owner"],
|
||||
"summary": "<you> Created <your-object> in <some-context> and <some-other-context>, and are delivering this activity addressing <context-owner> and <other-context-owner>."
|
||||
"id": "https://domain.example/some-object",
|
||||
"context": "https://domain.example/some-context",
|
||||
"summary": "<some-object> exists in <some-context>."
|
||||
}
|
||||
```
|
||||
|
||||
It may be that you are refused addition into some context, but granted addition into some other context:
|
||||
You wish to browse that context, so you dereference the context:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/context-1-activity",
|
||||
"actor": "https://domain.example/context-owner",
|
||||
"type": "Reject",
|
||||
"object": "https://domain.example/your-activity",
|
||||
"summary": "<context-owner> Rejected <your-activity>.",
|
||||
"content": "Sorry, I don't want to add your object to my context."
|
||||
"id": "https://domain.example/some-context",
|
||||
"attributedTo": "https://domain.example/context-owner",
|
||||
"type": "https://w3id.org/fep/xxxx/Conversation",
|
||||
"https://w3id.org/fep/xxxx/posts": {
|
||||
"id": "https://domain.example/some-context/posts",
|
||||
"type": "OrderedCollection",
|
||||
"items": [
|
||||
"https://domain.example/some-object",
|
||||
// ...
|
||||
]
|
||||
}
|
||||
"summary": "<some-context> is owned by <context-owner>. It is a <Conversation> and it has a canonical collection of <posts>, which is <some-context/posts>."
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/context-2-activity",
|
||||
"actor": "https://domain.example/other-context-owner",
|
||||
"type": "Add",
|
||||
"object": "https://domain.example/your-object",
|
||||
"target": "https://domain.example/some-other-context/collection",
|
||||
"summary": "<other-context-owner> Added <your-object> to <some-other-context>."
|
||||
}
|
||||
```
|
||||
|
||||
A third-party observer encounters your object:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "https://domain.example/your-object",
|
||||
"context": ["https://domain.example/some-context", "https://domain.example/some-other-context"],
|
||||
"content": "Hello!"
|
||||
}
|
||||
```
|
||||
|
||||
They attempt to verify that your object is included in the first context, and find that it is not included:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-context/collection",
|
||||
"attributedTo": "https://domain.example/other-context-owner",
|
||||
"type": "OrderedCollection",
|
||||
"orderedItems": ["https://domain.example/some-object", "https://domain.example/your-object"],
|
||||
"summary": "<some-other-context/collection> is an OrderedCollection owned by <other-context-owner>. It currently contains <some-object> and <your-object>."
|
||||
}
|
||||
```
|
||||
|
||||
The third-party observer attempts to verify that your object is included in the second context, and finds that it is included:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://domain.example/some-other-context/collection",
|
||||
"attributedTo": "https://domain.example/other-context-owner",
|
||||
"type": "OrderedCollection",
|
||||
"orderedItems": ["https://domain.example/some-other-object", "https://domain.example/your-object"],
|
||||
"summary": "<some-other-context/collection> is an OrderedCollection owned by <other-context-owner>. It currently contains <some-other-object> and <your-object>."
|
||||
}
|
||||
```
|
||||
|
||||
The third-party observer's client renders your object as unverifiably within some context, and verifiably within some other context.
|
||||
|
||||
```text
|
||||
<you> Created <your-object>
|
||||
<your-object> has content: "Hello!"
|
||||
<your-object> is part of the following contexts:
|
||||
- <some-context> (❓ unverified)
|
||||
- <some-other-context> (✅ verified)
|
||||
```
|
||||
|
||||
The third-party observer may then choose to navigate to (and possibly participate in) the latter context.
|
||||
As a consumer, you can browse or backfill the conversation by loading the context's canonical collection. In the above representation of `<some-context>`, the use of the hypothetical `https://w3id.org/fep/xxxx/Conversation` type would indicate that the associated canonical collection is exposed via the hypothetical `https://w3id.org/fep/xxxx/posts` property.
|
||||
|
||||
---
|
||||
|
||||
@@ -528,6 +397,9 @@ Because [PUB] does not define the use of `context` as a property or the notion o
|
||||
|
||||
[PUB]: https://www.w3.org/TR/activitypub/
|
||||
[VOCAB]: https://www.w3.org/TR/activitystreams-vocabulary/
|
||||
[GH300]: https://github.com/w3c/activitystreams/issues/300
|
||||
[GH238]: https://github.com/w3c/activitystreams/issues/238#issuecomment-153408442
|
||||
[AUDIENCE-AND-CONTEXT]: https://www.w3.org/TR/activitystreams-vocabulary/#audience-and-context
|
||||
|
||||
## Copyright
|
||||
|
||||
|
||||
Reference in New Issue
Block a user