Recently, I joined a research project at MIT called Graffiti, which conveniently has a broken website right now. Now before I explain the project, I’m going to talk about what I’ve increasingly come to see as the biggest technical problem with ActivityPub.

Unnecessarily building up suspense…

Wait for it…

ActivityPub servers conflate storage with processing.

Blah blah blah, what does that even mean? Basically, ActivityPub servers currently do way too many things. They handle storage, messages, and forwarding. Pretty reasonable. They can handle streaming and uploading videos, in the case of PeerTube. They can handle code hosting and collaboration, in the case of Forgejo. And on and on. Every server has its own implementation of storage and messaging.

And how do people access stuff on ActivityPub servers? They use the server’s web client or a client app. And if they use a client app, that app is probably using a Mastodon API clone or something similar.

It doesn’t have to be like this.

The ActivityPub protocol is actually two closely-related but distinct protocols: server-to-server (S2S) and client-to-server (C2S). Server-to-server is the boring old federation stuff you’re used to: it describes how servers should deliver messages to other servers to propagate actions throughout the network. Now client-to-server is much spicier. It’s ActivityPub’s hidden superpower.

C2S offers a standardized way for clients or bots to interact with ActivityPub servers and data stored on that server. In an alternate universe, imagine if all your ActivityPub server did was store data and handle messaging and forwarding. Now let’s say we want to implement something like PeerTube. We’d split it into two parts: a client app and a processing app. The client app can be either a website or a normal app, which people use to view videos, comment, like, whatever via C2S. The processing app can be a bot that handles stuff like transcoding videos. Crucially, the processing app can also use C2S. It’s basically just a bot.

It gets better. Have you ever been frustrated about having a Mastodon account and a PeerTube account and a Forgejo account and a Lemmy account and so on? With this system, you just need one account, and all the processing apps operate on the data of your one account. Boom. Problem solved.

It’s also compatible with the ActivityPub spec and existing implementations. Hooray!

This gives us an explosion of possibilites for what we can now do with ActivityPub. Now literally anyone can run an ActivityPub app. Just run the processing app on your computer, or even a phone. You don’t need a domain name or web server or anything.

Except… this isn’t all rainbows and sunshine. Separating storage and processing like this introduces latency and hurts performance. Another possibility is that we could make the ActivityPub server also handle running sandboxed user-uploaded processing apps, so that the processing apps can be physically close to the storage.

What about security? We don’t want processing apps to have access to read and write all your data, so maybe a capabilities system would be useful here.

The upshot of all of this is that if you want to write an ActivityPub app, you no longer need to worry about handling OrderedCollections or forwarding activities or any of that. You just need to write a C2S bot.

I told you earlier that I was going to explain that research project, but now you already know what it’s about. The stuff above.

So you might be wondering, sure these ideas sound amazing, but do they actually work? And my honest answer is I don’t know. I glossed over way to many technical details. The whole point of this post isn’t to declare this is the panacea to all of ActivityPub’s technical woes, but rather to get your brain spinning and thinking. And don’t forget that by far the toughest challenges for the fediverse are not technical, but rather social, like moderation or these challenges. We can’t stop arguing over which decentralized web protocol is best while really it’s the social problems that need solutions.

Bonus! Let’s solve another notoriously difficult ActivityPub problem: nomadic identity. (Much of this is copied from this braindump of decentralized protocol ideas)

The trick here is to use public keys as user identifiers. Instead of billiam@centipete.exozy.me, you’re now 1a59726c1da670d0cbc20b97b7f32a3b6df1daef911384b0d4144c8b986ab68f or something. Well, that kinda sucks.

Let’s add a petname system to the mix. This gives us human-readable names. Yay!

We just need to figure out which server a user belongs to based on their public key. In theory, you can use a DHT. In practice, you can probably use a DHT, but the details are kinda flaky here. Basically, when you want to find a user’s server, you query a DHT formed by all servers. This returns a string containing their server’s URL or some other address, signed with that user’s private key to prevent tampering.

Now to migrate from one server to another, all your data is stored at one place, so you can simply copy it over. Easy as that. Perhaps you could even have your data replicated on multiple servers using primary-secondary replication, and then if you get injustly banned on your primary server, you can designate one of your secondary servers as your primary server.

This scheme has a few major problems. Obviously, if your private key leaks, you are screwed. Oops. Additionally, DHTs kinda suck. I know that because I tried writing one once and it kinda sucked and all the DHTs I’ve ever used have kinda sucked. So YMMV. Also, this scheme breaks any semblance of compatibility with the ActivityPub spec, so it’s mostly just for fun and for exercising your brain.

Hope this was interesting! If you have any feedback or related ideas, just reply to this post Oh, and by the way, Hubzilla has probably solved these problems way better than anything I proposed, because Hubzilla is awesome and criminally underrated.