Standardising objects with revisions

Hello, I’m planning on developing a messaging app based on ActivityPub.
I want edit history feature for best dependability but there don’t seem to be working standard for it.

From https://chat.indieweb.org/social/2019-10-10/ :

doublequartz: hey guys! I’m implementing ActivityPub. however I have a question… what I should do if I want to edit a message while keeping the old one intact in history?

jaywink[m]: ah right. probably an OrderedCollection on the Note for the revisions, for example? but yeah AP C2S probably doesn’t have anything for you here

If we replace content with an OrderedCollection including every revision, we’re going to have linearly increasing performance cost.
I think creating an OrderedCollection with link to all revisions when an object is updated for the first time would scale best.

Although the peers can store objects before Update all they want, the original sender fails to provide a consistent id for the old version. There should be a way to make reference to old versions that fediverse can understand.
I don’t have much experience on social networking applications and I have no idea what kind of trouble “object versioning” would bring. I appreciate explanation on this.

[2019-12-15 09:13:34+0000] doublequartz via SocialHub:

If we replace content with an OrderedCollection including every revision, we’re going to have linearly increasing performance cost.
I think creating an OrderedCollection with link to all revisions when an object is updated for the first time would scale best.

The way it will probably be done in pleroma is to store only the difference (like the diff program) so it scales well for large posts. I think there should be a more or less standard field so all peers can grab the history of an Activity, specially so that the replies can be nicely displayed depending on that (I think it can work well in pleroma-fe thanks to it’s ability to show the parent post btw).

And yeah not really sure about how post history + editing visibility would go, specially if you restrict it further. Maybe it should only store the history for the text fields visible to the user (content, summary, title, …).

Although the peers can store objects before Update all they want, the original sender fails to provide a consistent id for the old version. There should be a way to make reference to old versions that fediverse can understand.
I don’t have much experience on social networking applications and I have no idea what kind of trouble “object versioning” would bring. I appreciate explanation on this.

The kinds of trouble could be:

  • Editing a post where you heavily change it’s meaning to troll the repliers
  • Further ways a server could lie about the objects it has (but I think this one is a bit moot as there is enough people using multiple instances)
2 Likes

@cwebber Any thoughts ? btw:
In this closed issue you said :
“ActivityPub only supports GET/POST”
How about JSON Patch with POST ?

If we combine it with diff it would be something like

[2019-12-17 06:44:14+0000] Sebastian Lasse:

@cwebber Any thoughts ? btw:
In this closed issue you said :
“ActivityPub only supports GET/POST”
How about JSON Patch with POST ?

If we combine it with diff it would be something like
https://github.com/benjamine/jsondiffpatch

Looks like a good one in theory, will try it in pratice (Elixir or Go) if I have time for it, format documentation is on https://github.com/benjamine/jsondiffpatch/blob/0c4323e9bff23ae231f4bff231ceed4df2b48be5/docs/deltas.md btw in case you’re not finding it in the readme (and unidiff is diff -u in case you’re wondering/want to be sure).

1 Like

One way of doing this is linking the new object to the old object with dcterms:hasVersion (https://www.dublincore.org/specifications/dublin-core/dcmi-terms/#terms-hasVersion).

Example:

{"@context": [ "https://www.w3.org/ns/activitystreams", {"dcterms": "http://purl.org/dc/terms/"}],
 "type": "Create",
 "id": "https://social.example/alyssa/posts/a29a6843-9feb-4c74-a7f7-081b9c9201d3",
 "to": ["https://chatty.example/ben/"],
 "actor": "https://social.example/alyssa/",
 "object": {"type": "Note",
            "id": "https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19",
            "dcterms:hasVersion": "https://social.example/alyssa/posts/old-version",
            "attributedTo": "https://social.example/alyssa/",
            "to": ["https://chatty.example/ben/"],
            "content": "Say, did you finish reading that book I lent you?"}}

The client could then understand that there is another version of the note available (“https://social.example/alyssa/posts/old-version”) and retrieve it. The version history is a linked list of post.

We had to extend the context with {“dcterms”: “http://purl.org/dc/terms/”} so that it is exactly clear what “dcterms:hasVersion” means.

I think this is a nice example of an extension to ActivityPub. It is standard conform (valid JSON-LD), uses a widely established vocabulary (dcterms) and clients who don’t know what to do with “dcterms:hasVersion” just ignore it.

1 Like