Recently, there was a discussion about generic #ActivityPub servers.
-
> I think FEP-1b12 Announce is not compatible with ActivityPub. It has different side effects, doesn't update shares collection.
Why?
Updating the shares collection is orthorgonal to the behavior expected from a Group actor that claims to support 1b12.
Sure, you can say that if the server does not update the shares collection, it's not fully compliant with AP APi, but there is nothing a Lemmy server to add every activity to the shares collection.
@raphael Nevermind, side effects wouldn't be a problem. However, it still doesn't seem to be compatible with ActivityPub... Because
Announceactivity is not defined in C2S context
ActivityPub
The ActivityPub protocol is a decentralized social networking protocol based upon the [ActivityStreams] 2.0 data format. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and content.
(www.w3.org)
-
@raphael Nevermind, side effects wouldn't be a problem. However, it still doesn't seem to be compatible with ActivityPub... Because
Announceactivity is not defined in C2S context
ActivityPub
The ActivityPub protocol is a decentralized social networking protocol based upon the [ActivityStreams] 2.0 data format. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and content.
(www.w3.org)
@silverpill @raphael @julian @mariusor
In my book if a side effect is part of the protocol specification, then it constitutes a protocol capability. If not, then it is part of some app's / solution's business logic.
The definition of "ActivityPub extension" by itself is unclear. With overloaded use causing confusion. It may refer to:
- Protocol extension
- App / solution built on top of the protocolTo deal with protocol capabilities they must have water-tight specs, well-defined behavior and strict consistent use across the fediverse.
To deal with side effects that are part of solution designs for a particular application or business domain things go from simple to very complex in the amount of introspection and machine-readability that the #ActivityPub Actor abstraction offers.
Simplest is finding the URL where the docs of the extension / solution design sit. Most complex is full introspection and handshaking. The latter is the Solid route.
🫧 socialcoding.. (@smallcircles@social.coop)
Attached: 1 image I recreated an old diagram in Excalidraw that I spread about a couple years ago, and made it a bit more informative. Explanation can be found in the #AltText See also and for discussion: https://discuss.coding.social/t/diagram-interoperability-in-practice/828 Or join the Social experience design chatroom at: https://matrix.to/#/#socialcoding-foundations:matrix.org Also posted to #SocialHub at: https://socialhub.activitypub.rocks/t/activitypub-versus-fediverse-interoperability-in-practice/8498 @ben@werd.social #SX #SocialCoding #SocialWeb #ActivityPub #SolidProject #fediverse
social.coop (social.coop)
-
Recently, there was a discussion about generic #ActivityPub servers. Several people claimed that they were working on one, but it turned out that their "generic" servers only support activities defined in the ActivityPub specification. Such a server shouldn't be called generic. It is not difficult to build, neither it is an interesting concept because competing protocols (e.g. Nostr) already offer much more.
I've been writing a #FEP that describes how to build a real generic server. It is not finished yet, but I feel like now is a good time to publish it:
FEP-fc48: Generic ActivityPub server
This kind of server:
- Can process any object type, and can process non-standard activities like
EmojiReact.
- Compatible with FEP-ae97 clients.
- Does not require JSON-LD.I attempted to implement it when I was researching security properties of FEP-ae97 API: https://codeberg.org/silverpill/fep-ae97-server. Back then I didn't know what to do with side effects, but now I think that we can simply force clients to specify them.
I e*love* this idea- especially in principle. I say that because I’m having a hard time wrapping my head around this and how it would be used in practice.
Do you think you could post an example workflow (or three) to demonstrate how this would work?
I get that objects could be added to client-defined collections (very cool) but if object/collection IDs don’t have predefined semantics, how will I know where to look to get the data I need?
-
what Vocata did
This project is often brought up as an example of a generic server, but it never reached production stage. The last commit was in 2023.
It is one thing to have an idea and build a prototype, and a completely different thing to build an application that is secure and interoperates with the rest of the network.
@silverpill @raphael @mariusor
> neither is it an interesting concept
> interoperates with the rest of the network
look, we clearly have different goals here. your goal is to interoperate with the mastodon network. my goal is to publish activities to my website. mastodon doesn't even support all the activities defined in AS2-Vocab. a generic server supports *any* activity, even those not defined by AS2. the network i want to interoperate with isn't mastodon, it's the web.
-
I e*love* this idea- especially in principle. I say that because I’m having a hard time wrapping my head around this and how it would be used in practice.
Do you think you could post an example workflow (or three) to demonstrate how this would work?
I get that objects could be added to client-defined collections (very cool) but if object/collection IDs don’t have predefined semantics, how will I know where to look to get the data I need?
@benpate @silverpill @mariusor none of the IDs should have any semantics; from the outside, there is no distinction between a client managed or server managed collection. likes/shares/etc could be managed by a "client" like mastodon, or even a "default" one. it's not any more complex unless you want to vary the collection responses based on the request headers. for that you need a minimal dynamic layer with an access control policy of some sort. (WAC is the simplest, but ACP is more powerful)
-
@benpate @silverpill @mariusor none of the IDs should have any semantics; from the outside, there is no distinction between a client managed or server managed collection. likes/shares/etc could be managed by a "client" like mastodon, or even a "default" one. it's not any more complex unless you want to vary the collection responses based on the request headers. for that you need a minimal dynamic layer with an access control policy of some sort. (WAC is the simplest, but ACP is more powerful)
@benpate @silverpill in a client managed followers collection i would Add you to my followers just like fedi instances currently do silently. "but how can you prove--" yes exactly, how can current fedi prove anyone is a follower either? you need the Follow+Accept pair to both be live without an Undo on either, right? and that's what leads to the "follow state machine" on fedi that drifts out of sync and leads to private posts being leaked to removed followers (which you can't officially do!)
-
I e*love* this idea- especially in principle. I say that because I’m having a hard time wrapping my head around this and how it would be used in practice.
Do you think you could post an example workflow (or three) to demonstrate how this would work?
I get that objects could be added to client-defined collections (very cool) but if object/collection IDs don’t have predefined semantics, how will I know where to look to get the data I need?
@benpate Let's assume that my client is a music player. It publishes a
Listenactivity whereobjectis anAudio. This activity should increaseplayCounton theAudioobject.One way to support this on the server side is to teach it about
Listen,Audioand how to updateplayCount. This is how most existing servers are built.But a server described in my FEP would work differently:
- It doesn't know anything about
Listen,AudioorplayCount.
- Upon receivingListen, it will recognize it as an activity, and embeddedAudioas an object.
- Since this is not a CRUD operation, it will not check permissions.
- IfListenactivity has aresultproperty, the server will process that activity as well.
- Ifresultis anUpdateactivity, the server will recognize it as a CRUD operation and will check permissions:Update.actorandAudio.attributedTomust be the same.
- The server will save both activities,ListenandUpdate.
- Then it will deliver them to intended recipients (toandcc).Effects are client's responsibility now, it must provide an
Updateactivity if it wants to updateplayCount. There are other requirements too, for example all objects should have anattributedToproperty, which is needed for permission checks.But in this setup a single server can work with any kind of client.
-
@silverpill @raphael @mariusor
> neither is it an interesting concept
> interoperates with the rest of the network
look, we clearly have different goals here. your goal is to interoperate with the mastodon network. my goal is to publish activities to my website. mastodon doesn't even support all the activities defined in AS2-Vocab. a generic server supports *any* activity, even those not defined by AS2. the network i want to interoperate with isn't mastodon, it's the web.
-
The crux of the issue is that we shouldn't need to talk about "your FEP" when we are talking about "servers focused on implementing the ActivityPub API". The spec as is *is enough*. You are moving the goal posts by pushing a definition of "generic server" when it doesn't need to,and you are creating a "No True Scottsman" by saying that implementation X, Y or Z is "incompatible" with ActivityPub API.
@trwnh @mariusor -
The crux of the issue is that we shouldn't need to talk about "your FEP" when we are talking about "servers focused on implementing the ActivityPub API". The spec as is *is enough*. You are moving the goal posts by pushing a definition of "generic server" when it doesn't need to,and you are creating a "No True Scottsman" by saying that implementation X, Y or Z is "incompatible" with ActivityPub API.
@trwnh @mariusor@raphael @silverpill well, it's missing a way to remove a follower, but otherwise the "POST to outbox" bits are mostly clear. except how the outbox delivery algorithm handles collections, which when they have inboxes, doesn't allow delivering only to that inbox instead of recursing over all items' inboxes.
otherwise i think "side effects" are a red herring. using as:result can be helpful but the "side effects" should happen in an attached client and should be called "automation".
-
@benpate Let's assume that my client is a music player. It publishes a
Listenactivity whereobjectis anAudio. This activity should increaseplayCounton theAudioobject.One way to support this on the server side is to teach it about
Listen,Audioand how to updateplayCount. This is how most existing servers are built.But a server described in my FEP would work differently:
- It doesn't know anything about
Listen,AudioorplayCount.
- Upon receivingListen, it will recognize it as an activity, and embeddedAudioas an object.
- Since this is not a CRUD operation, it will not check permissions.
- IfListenactivity has aresultproperty, the server will process that activity as well.
- Ifresultis anUpdateactivity, the server will recognize it as a CRUD operation and will check permissions:Update.actorandAudio.attributedTomust be the same.
- The server will save both activities,ListenandUpdate.
- Then it will deliver them to intended recipients (toandcc).Effects are client's responsibility now, it must provide an
Updateactivity if it wants to updateplayCount. There are other requirements too, for example all objects should have anattributedToproperty, which is needed for permission checks.But in this setup a single server can work with any kind of client.
Yes, I think I like the idea of clients being able to store data on the server however they like. It reminds me of this description of ATProto that I found recently: https://overreacted.io/a-social-filesystem/
I guess my question is: once I store my custom stuff in custom places on my server, how do I publish this so other people can find?
And, object IDs are usually defined by the server. So how would it work to say "create a collection named XYZ and add this object to it"?
-
Yes, I think I like the idea of clients being able to store data on the server however they like. It reminds me of this description of ATProto that I found recently: https://overreacted.io/a-social-filesystem/
I guess my question is: once I store my custom stuff in custom places on my server, how do I publish this so other people can find?
And, object IDs are usually defined by the server. So how would it work to say "create a collection named XYZ and add this object to it"?
> object ids are usually defined by the server
the server would need to know your namespace/prefix, then mint ids in that namespace. if that is a dns name, then you get dns portability. if it's an https uri, then you ideally need to support relative references and redirects.
"create a collection" can happen over any CRUD method supported. if you use AP as an API then this would be a Create(object.type=Collection) then you get HTTP 201 Created with a Location header.
-
Recently, there was a discussion about generic #ActivityPub servers. Several people claimed that they were working on one, but it turned out that their "generic" servers only support activities defined in the ActivityPub specification. Such a server shouldn't be called generic. It is not difficult to build, neither it is an interesting concept because competing protocols (e.g. Nostr) already offer much more.
I've been writing a #FEP that describes how to build a real generic server. It is not finished yet, but I feel like now is a good time to publish it:
FEP-fc48: Generic ActivityPub server
This kind of server:
- Can process any object type, and can process non-standard activities like
EmojiReact.
- Compatible with FEP-ae97 clients.
- Does not require JSON-LD.I attempted to implement it when I was researching security properties of FEP-ae97 API: https://codeberg.org/silverpill/fep-ae97-server. Back then I didn't know what to do with side effects, but now I think that we can simply force clients to specify them.
@silverpill @mariusor @trwnh In principle, I like the general idea, but I think it's misleading to call this an "ActivityPub" server FEP since it doesn't conform to the ActivityPub specifications. You also recommend (require?) using the `result` property to describe server side-effects, but you don't describe *how*. I don't know how you expect to "force clients to specify them".
-
@silverpill @mariusor @trwnh In principle, I like the general idea, but I think it's misleading to call this an "ActivityPub" server FEP since it doesn't conform to the ActivityPub specifications. You also recommend (require?) using the `result` property to describe server side-effects, but you don't describe *how*. I don't know how you expect to "force clients to specify them".
This FEP introduces new requirements to ActivityPub, and I will probably add more in the future. Does that make it non conformant?
In any case, I think calling it an ActivityPub server is appropriate.
Side-effects are activities, I will clarify that in the FEP. The value of
resultproperty can be an embedded activity, or an array of activities.Clients either specify them, or they don't get any side effects.
-
Yes, I think I like the idea of clients being able to store data on the server however they like. It reminds me of this description of ATProto that I found recently: https://overreacted.io/a-social-filesystem/
I guess my question is: once I store my custom stuff in custom places on my server, how do I publish this so other people can find?
And, object IDs are usually defined by the server. So how would it work to say "create a collection named XYZ and add this object to it"?
@benpate Publishing process doesn't change much. A generic server should deliver activities to actors specified in
toandccfields. It should keep track of collections, such asfollowerscollection, and "expand" them before delivery. This part is not different from the regular ActivityPub.I think ID assignment should also work the same. In the FEP I proposed
Addactivity withoutobjectas a special activity for creating collections, but now I see that it will not work if IDs are minted by a server (no FEP-ae97).Perhaps it should be a
Create, after all, as @trwnh described in an adjacent comment. I was hesitant to useCreatebecause this is a problem for FEP-ae97 clients (not a big one though).