Letterbook - No universal translators

It turns out that federating is really hard. But, I managed it. Now I would love to have your help with everything that comes after that.

Picard and an alien prepare face the creature at El-Adrel. A still frame from the ST:TNG episode Darmok
Joining the fediverse is kind of like this

If you're reading this, you probably know what the fediverse is. But let's be sure,  just in case. The fediverse is a network of independent—but interoperable—social networking servers. You can sign up for one of them and then talk to people on other servers, a little bit like email. Servers exchange data with each other over some shared protocols. That exchange of data and interoperability is what's known as federation. And thus we get the word fediverse, a portmanteau of federated universe. Federated services exist to support all sorts of scenarios like microblogging, photo sharing, and streaming video, to name a few. I'm building a service of my own, called Letterbook, that falls mostly into the microblogging category. (And I would love to have you join me!) In fact, I just hit a really significant milestone with it: Letterbook can now perform some real federated message exchanges.

(hold for applause)

If that doesn't sound hard, that's not surprising. I didn't think it would be either. Let me explain.

timeline
    title Zero to Federated
    section Ramp up 🏔️
    ActivityStreams             : Serialize : Deserialize : Polymorphic Types : No schemas : Extensions : W3ID sec vocabulary
    ActivityPub                 : API : Actors : Objects : Inbox : Outbox : GET : POST
    Persistance Layer           : Unique IDs -> absolute HTTP(s) URIs : Store & retrieve AP documents
    Webfinger API               : Depends on Persistance : Strictly required for Mastodon interop : Helpful for everyone else : Retrieve AP Actors, at least
    Federated Authentication    : Store & retrieve signing keys : Depends on ActivityStreams extensions : Depends on Persistance : Http-signatures : But, like, 20 draft revisions old
    Defered work queue          : Strictly required for interop : Not part of any spec 🙃 : You can now start testing
    section We are here! 🎉
    Your App                    : Basic features : User management : Unique features : All the things you started the project to do

I shared a timeline much like this one on Mastodon before. This is a reasonably good summary of what it takes to begin federating from scratch. There's a lot here, but I'm still probably forgetting things; and I know it elides a lot of ambiguity. If you were to read the spec and discussions about ActivityPub and then start implementing—like I did—you would likely recognize the sections in this timeline. The spec itself only consists of the first 2 columns: the data types, and how to send and retrieve them. That probably sounds straightforward. I thought so, too. I ran into problems immediately. To begin with, ActivityStreams consists of a set of data types that are only loosely described in a JSON-LD context document. The LD stands for Linked Data; it's a semantic web thing. The idea is to make data self defining. I see the appeal, but in practice, this makes parsing documents (and producing parsable documents) a very difficult and computationally expensive affair. In fact, I don't feel that parsing is even the word. I think it's essentially compiling, like you would do with software, except for documents. And like with software, that is brittle, and fraught with security concerns, to say the least. It also means that they're virtually impossible to define as static types. This is A Problem™.

Picard and Dathon at El-Adrel
–Unknown Tamarian

And that's just the first step. Every step on that timeline has been like this. ActivityPub depends on the ActivityStreams types to function as "social primitives", as they describe it. But it offers essentially no guidance on how to put them together. It also acknowledges that authentication is necessary and then says almost nothing about how to accomplish it. Object IDs must be globally unique, and also publicly resolvable URLs that you can store and retreive later. The means the communication protocol inserts itself into your application logic all the way down to the database. If you want to interoperate with Mastodon, and I do, then you must implement Webfinger, and an old superceded draft of HTTP message signatures, and my most recent favorite: you have to implement a deferred work system. None of which is in any spec. If you want to test anything, you have to figure out how to build and run some peer services yourself.

💡
Strictly speaking, that last part is only partially true at this point. But that's only because I built a reusable solution for running peer instances to test against.

This is not to complain, although I may do that later. I'm trying to convey the extent of both the complexity in setting up a new federated service, and the ambiguity. It's a very steep curve, and there are essentially no known paths to follow. You have to rediscover and reinvent everything for yourself. And the coordination that a set of specs and developer community might suggest just isn't present, somehow. So every time someone new climbs that slope, instead of becoming more well-trod, it just erodes further, and new potholes appear. Everyone has to learn how to talk to each other all over again. Every new service is a new Darmok, meeting Jalad at Tanagra. (If you don't get these references, that kind of helps illustrate my point. But you should watch, or at least read the summary of the Star Trek TNG episode Darmok.)

In all honesty, I worry I'm having the same effect. That's part of the reason I'm writing this now, and will write more later. The other reason is to invite you (yes, you, reading this) to join in and help build Letterbook.

Things are only impossible until they are not
–Jean-luc Picard

Joining the Federation

Letterbook is a social media app. It's for people, and communities. It's going to prioritize safety, cost, and ease of use. And it's also going to prioritize enabling people to have conversations with each other. To talk. To share. To be in community. I want the project itself to also be a community effort. The ramp up to get to this point was longer and harder than I expected. It turns out it was a steep mountain. But, we're at the top of that mountain now, and we can start to see what's beyond it. Don't get me wrong, there are so many more mountains to climb. But right now, the path is downhill. It's a perfect time to join. We have established patterns, and working examples, but also vast swathes of unimplemented fundamental requirements. You can learn the domain, the stack, and the system while most of the work is very straightforward. And you can guide which mountains we climb next. If you want to write code, there's plenty of that. Skip ahead. First, I want to talk about all the other things.

Research and Documentation

To a large degree, this is on me. There's a lot of things that only exist in my head right now. I'm going to spend a good chunk of time in the near future writing them down. But I don't know everything. I have some informal community management experience, but nothing like content moderation or trust & safety. I know the tools that exist now are innadequate, but I don't know what would be better. I know Mastodon is both hard and expensive to run, but I don't know specifically in what ways. I have a lot of experience building and running software myself, but not to package and publish for strangers to run. These are things I know that I don't know. There's any number of unkown unkowns, too. I could really use help with that, even if you never wrote a single line of code. Honestly, I would love nothing more than to have the help of a librarian.

Design

I say design in the broadest sense. Yes, UI and UX design are top of mind for me, but it's more than that. In a modern tech company, what I have in mind would be done by the Product™ team. But, before the invention of capital-P Product, these things were done by designers. I want to know more about what people want and need from a social media service, so that I can satisfy those needs. I know enough about that to know that I really wish I had some experts to lead the way.

This also includes some level of graphic design. I wish the project had a logo, an aesthetic, and a visual language. I have ideas about this! I do not know how to execute them! Please talk to me if this interests you!

Coordination

When I say coordination, I mean the kinds of things you might think of as project and community management. I'm trying to make the project approachable, and easy to explore. But, this may (not) surprise you: I'm strongly introverted. Doing that is work for me, and definitely not easy. I know I could be doing better in this regard.

Code

Letterbook is open source software, it will of course always need code contributions. It's built in C#, using ASP.Net Core and Entity Framework Core. I've made a start at an authentication and identity management system using ASP.net Identity (worth a post on its own). We're using (and substantially contributing to) ActivityPubSharp for managing AP documents. Many thanks and kudos to Hazel for their work on that so far.

The intent is to implement the Mastodon API, and thus support existing Mastodon clients. I don't yet know how well that will work, but it's the plan. Regardless, we will also need our own frontend, because we're not just reimplementing Mastodon. This doesn't exist yet at all. I'm very open to suggestions, and contributions, on that stack.

We also need to build out a ton of basic backend features. For example, you can't actually post right now. I've tried to go deep through the process to working federation, because that's so much of the value proposition for this project. Now that I'm there, everything else can build out around that.