You have a right to cache the payload, unmodified. So youâre correct, server_b
will locally store federated payloads from server_a
, meaning it is up to your specific application whether you want your appâs logic to:
- Store everything ever sent to you and rely heavily on your cache; or
- Just store the IRIs and then re-fetch from a peer server whenever you need the body of the object (no caching); or
- something in between
That is application-specific. In todayâs software, typically only the original actor sends an Update
Activity â if the software even allows Updates at all.
The question of âwho can do whatâ is again, unfortunately, application specific. The Update
and Delete
Activities are sent out to allow coordinated âcache controlâ of these copies living in other federated peers. Some applications skip the Update
logic and only federate Create
and Delete
.
I think a key point of confusion may be: In your example, you have a cross-instance federated Update
. That is, https://anotherone.net/thomas
is attempting to Update
something originating from https://example.com/
. This is not the simple case, but a very gnarly case due to how IRIs today are coupled with their originating server. I think there are discussions on this SocialHub going into great debate trying to solve this kind of general problem (âsending an activity about data living on another instanceâ) but Iâd propose excluding it for now, and revisiting it later.
With that in mind, that means an appâs primary focus is going to figure out if it should let only the original actor also send an Update
about the data it âownsâ â letting only https://example.com/max
send an Update
for https://example.com/max/task_72
â or allow anyone on https://example.com
send that Update
. I canât remember off the top of my head if some peer software already bakes that assumption into their processing of incoming federated activities, in which case it is also a compatibility problem now.
One point of detail: the Activity
may have the actual data youâre interested in (Task
, in this case) embedded in its body. I think most implementations rely on IRI indirection here. For example, a complete discovery round of fetching could look like this:
- Fetching
https://example.com/max/outbox
may yield:
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "OrderedCollection",
"totalItems": 4,
"orderedItems": [
"https://foo.bar/baz/1",
"https://server_a.com/max/activity_0815",
"https://example.com/something/else/123",
"https://server_b.com/max/activity_0004"
]
}
2a) You then iterate â Iâll just go through one iteration here â and fetch the first orderedItem
:
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Update",
"id": "https://foo.bar/baz/1",
"actor": "https://foo.bar/thomas",
"object": "https://example.com/max/task_72",
"to": "https://example.com/max"
}
2b) You then fetch https://example.com/max/task_72
and obtain the latest version of it (note: this will also be the same payload when fetching the Create.object
for this task):
{
"id": "https://example.com/max/task_72",
"type": "Task",
"status": "DONE",
"assignee": "https://anotherone.net/thomas"
}
- If still iterating, go to 2a.
Ignoring the cross-federated update, the simple path is: each instance of federated software is able to âownâ and operate on (update and delete) their own data, but share it. Peers receiving that data can then generally generate new data in response to such data, and also share it. They can also locally delete it (ex: moderation) but it does not result in mass censorship for other federated software instances.
Iâm not sure what interactions youâre interested in, but if that previous paragraph is insufficient for your use-cases, youâre not alone. Great questions!