honk is my take on a federated status updater. One might say it’s opinionated software. Since my opinions are correct, this makes honk the world’s first provably correct social media application. Here’s a formerly brief rundown of things that work, things that don’t work, and things that won’t work. Plus some complaints about how other people do things. The version number, 0.1, indicates your expected level of satisfaction.
The version is no longer 0.1 and thus various statements made here may be less true.
We have some activity we’d like to announce to the world. “I’m fixing a bug.” “I’m drinking a beer.” “New beta out today.” “Hold my beer. I’m remounting the database filesystem async.” Whatever. Some people call this microblogging. I prefer the term radiating stati. Each status is broadcast, then rapidly decays. Some few are captured and amplified and rebroadcast. Science is scary, though, so henceforth radiating stati will be referred to as honks.
If your post is expected to have some nontrivial lifetime, I think it’s better suited for a blog or such. honk isn’t the best option for that. I associate low friction with low effort. Not to say this is bad, and I obviously believe there’s at least some value to shooting off a low friction note. honk is not exactly single purpose, but it’s certainly better at some things than others.
honk is more or less functionally literate in the ActivityPub language of the federation. AP has a verb object vocabulary. You can like a note, or follow a person, etc. But it’s pretty free form so lots of technically possible messages are nonsense. You can like my followers or I can follow your like. Furthermore, the underlying ActivityStream spec provides some guidelines on how to interpret the data you get, but pretty much every field is optional. The wonders of stringly typed data interchange. honk processes such messages as it understands, and stares with bemusement as the rest get dropped on the floor.
yet or not yet
Public RSS works. I wanted to add private RSS, so I don’t have two web pages to poll, but I wonder if maybe the flow should be reversed. RSS reader should post to honk? I notice that many people have more or less replaced RSS with Twitter. It’s probably too early to turn off RSS, but given that we now have push technology like ActivityPub, we can start building on it. (Note to the dude polling flak’s RSS every two minutes: I don’t post that frequently.) All the pieces are here, I just need some time to figure out how to arrange them.
You can upload and attach one picture. Has to be a picture. It will be resized and requantized down to a reasonable size. That code comes from an incomplete experiment in browser image editing, which also had some additional operations like cropping which didn’t fit in the current UI. This kind of feels like feature creep, but I think if you can post text, and there’s a text editor, and you can post images, then there should be an image editor. I don’t make you write posts in vi and upload text files.
Incoming attachments must also be images. I suppose video/mp4 could be supported, but I have not yet regretted its absence. honk does not yet optimize incoming images, but some of you need to go on a data diet.
Only notes, to use the AP term, are currently supported. Documents, articles, or pages, as might be announced by a blog, are not because I don’t have any test servers, but that’s a natural feature addition. This would fit nicely with the five year plan for RSS convergence.
Some information is lost as AP notes are converted to honks. For example, if you announce a note created last week, it will be saved with today’s date. The honk schema is noun based, while AP vocabulary uses verb noun combos, each of which can have their own actor, date, etc., and only one gets saved.
There are no size limits to honks. I think the medium is better suited for shorter messages, but there’s no reason to impose artificial limits. Here’s a nickel, kid. At the same time, while you can reply to self, threading looks like shit in the web client. This entire post could have been released as a series of honks. It was not. If you need more space, use it. Don’t man thread.
honk does not hide sensitive content.
Multiple users should be supported, but I’m not so crazy as to use this myself. Adding a second user is a manual process however. Hosting many users on a single instance kind of defeats the purpose in my opinion.
I don’t think any federation software supports virtual domains (cname hosting) very well. Given the push to owning your identity, I’d think people would have learned their lesson that your identity name should not include your provider name. Hopefully honk remains simple enough that it’s feasible for a provider to just run an instance per identity.
But a more functional admin interface (likely tty based) would be useful. Currently you get to use sqlite3 for such tasks.
The web interface is the only client interface. No desire to add any other API, however it wouldn’t be too much more work to get AP client based outbox going. I’m not writing the client though.
I wanted to go with a purple and gold color scheme, using gold to highlight new stuff and active elements, but didn’t find a yellow I liked, so we ended up kinda monochromatic. Not entirely pleased with the display of honks. The public side is fine, but on the private side it’s not easy to tell who and what and why apart. Like every web site I build, there’s an odd assortment of padding and margin specifiers in the CSS.
You need to search the page for mentions. Actual meaningful notifications would be helpful, but fell a little outside my immediate use case.
You don’t get to pick your avatar. Instead it will be assigned by the NSA. You will like it.
There’s no emoji support yet, but that’s definitely coming.
There’s no filtering or list management. I find pf works pretty well for filtering. Could use some work here if you’re a follower hoarder. The lack of prioritization is fine if you don’t mind missing updates, but I can imagine that getting annoying.
hashtags don’t work. I’m not sure exactly what the use case is. A certain amount of federation convention ironically seems to assume that everybody is on the same instance with symmetric views.
You can’t edit or delete a honk. Be like me; don’t make mistakes. An incoming deleted message will be converted to a zonk to indicate deletion, but it doesn’t disappear entirely. You put it in my inbox, it’s mine now. Update messages aren’t supported either, although in practice I haven’t seen any. Just deletes and reposts. This strikes me as being the wrong way around, since the deleted note’s URL is still out there in the ether. It would be better to fix the content it refers to than to republish at a new URL.
There’s no search or paging. I mostly view older content as expired content. In other words, no stepping in the same river twice. This could be added, just not a priority. The one feature I’d kind of like is “on this day” year later callbacks. I find last year’s news more interesting than last week’s news. Have a year to figure out how to build this feature, though.
No attention seeking. No likes, no favorites, no pins, no stars, no clapping, no counting. I think a big part of social media dysfunction comes from score keeping. Following is necessary for the protocol to work, but there’s no way to see who follows who in the UI, and like activities are dropped on the floor. Announcing (sharing) is supported because I think that’s a useful means to convey information, but there’s no count of such activities.
There is an almost complete peeping mode which follows someone via polling instead of subscribing to pushes. It was an artifact of testing, but it could be made to work if you’d like to discretely follow someone without your name showing up on their M profile.
Addressing and delivery are pretty complicated. AP has an email like addressing scheme, with to and cc, etc. But the audience for an activity may include other actors. On top of this, big M layers some additional semantics regarding to vs cc. And of course, most of the addressing is magically inferred from message content. It’s like writing an email client, except instead of address fields you start an email with Larry and it gets sent to Larry. And if you wanted to tell Susie “Larry is a jerk” well maybe you should try to be a nicer person. Anyway, honk mostly tries to address things properly, and reply nicely, and allow sending to somebody by beginning a honk with @.
However, everything goes to public. I prefer to think of federated private messages as public messages that simply haven’t leaked yet. honk should maybe give some indication that an incoming message wasn’t public to avoid surprises. In the mean time, don’t ask me any questions you wouldn’t ask your mother.
Delivery is the other side. You’re supposed to deliver to everybody in the audience, except some addresses can be lists. Like I reply to your message, and am supposed to cc your followers. Guess whose server gets to deliver those messages? Mine. This is really weird. Imagine if posting to a mailing list meant that instead of sending to the list server, you downloaded the full list of subscribers and then sent them all messages. And of course, maybe I can’t access your followers. Or I can access the list, but not everyone accepts messages from strangers. The AP spec has a section devoted to this. Your server is supposed to deliver to everyone my server couldn’t. But there’s no way to know who that could be. I think this is very messy. honk simply ignores collections. If you want to propagate the message, you do it. But I see no reason why honk should facilitate address harvesting and spamming. You don’t get to talk to my followers. They follow me, not you.
And then there’s something called shared inbox, where multiple users on one instance can have the same inbox to reduce the needed deliveries. Conceptually, great, but it’s most unclear how the server knows where the delivery goes. As noted, delivery, audience, and addressing don’t necessarily overlap so it’s not readily apparent how the receiver knows who to notify. If the receiving server wouldn’t notify a user, then the sender must not use the shared inbox. This requires the sender to guess what the receiver will do. Actually, a lot of the spec seems to work like that. Imagine what the remote server will do, and then use psychic coordination to send the kind of message that will produce the desired result. Alas, empathic programming doesn’t always result in robust systems.
Sadly, of the various bugs introduced during honk development, many related to addressing and delivery. Putting the wrong person in to or cc, or multiple times, or delivering a message back to yourself. Every step forward introduces new edge cases and complex interactions with every previous step. I’d rather have a feature set limited by design than unpredictable bugs.
honk only attempts to deliver outbound messages once. No retries. This is not best effort, but it is an effort. Queuing and retries is another step towards impending doom. I’m not yet worried about lost messages, but I guess we’ll get there. If email is the TCP of messaging, honk is the UDP.
While on the subject, I should mention rate limiting. I post a honk, with a picture of a delicious pickle, and it goes out to all my followers. These are small messages, great. Their instances will in turn immediately come back and download the attached picture, however, resulting in a flood of traffic. If a particularly popular follower shares the post, even bigger flood. There’s only so much honk can do here, since even trickling out outbound notes doesn’t control what happens when another instance shares it. Ironically, I think some M instances are spared from overload because other instances are already overloaded and unable to immediately process inbound messages. Once queuing is in place, I’d like to add some good neighbor rate limiting. I think there’s some potential for the AP protocol to specify that the announcing server should rehost the content, which distributes the load to the instances that cause it, but as far as I know nothing works like that today.
It’s unfortunate that the federation decided upon application mime types. I suppose there are reasons for this that I do not comprehend, but using a text mime type would have meant that most reverse proxy setups would gzip out of the box without additional configuration. I haven’t tried it, but I wonder what the success rate would be if I gzipped outbound posts. This is mostly a theoretical concern because honk messages are fairly trim, but other implementations pad them with all manner of extraneous information.
In addition to HTTP signatures, M will use JSON LD signature. Security considerations:
TODO: We need to add a complete list of security considerations. This includes a mention of something called RsaSignature2018. This same name appears on the Linked Data Cryptographic Suite Registry of all known Linked Data Key descriptions and their associated specifications. What does M use? RsaSignature2017. This name is not on the list. If you use RsaSignature2018, M will reject your messages. So what is RsaSignature2017? If you ask big M, the answer is read the JSON LD spec, which as noted, says nothing about RsaSignature2017. What’s the difference? It’s only crypto code, it’s not like precision really matters.
Anyway, back to the plot, M will occasionally forward messages for which the HTTP signature owner does not match the activity actor, because it’s trying to handle some of these weird ActivityPub cases. honk does not bother, and since there’s no clear specification for what you’re supposed to be doing, I’m not inclined to change that. As noted above, if we could use these signatures to reduce traffic, that’d be pretty cool, but mostly it seems to be used to send me more traffic.
Since I’m complaining about M, I’m still perplexed by all the account deletion messages I receive. They were filling my logs with noise since every message fails signature validation since the key is gone. Does nobody running M look at their logs, or does it not log such failures? I finally broke down and special cased this, by parsing the message first, and not complaining if the message is known noise. But parse first then validate is not how we build robust systems. This pains me.
Interop is mostly tested with big M. And with other honk instances, of course. What will happen with other implementations is a matter of some mystery.
I should write a spec explaining the database schema because that’s actually important.
The go build system has some annoying quirks. The vendor directory only works if building under the src directory of gopath. You can run go build outside gopath, but then it will ignore vendor. This seems almost completely backwards, since you can’t download a release of honk with all dependencies included and simply build it in a convenient location, as somebody not especially interested in go development may desire. You must setup a special directory structure first. Why why why. Not my fault. I recommend complaining to a higher power. (This seems to have been resolved by switching to using go modules combined with some magic incantations.)
In an experiment to combat bloat, the function names in honk are mostly whimsical nonsense. If the day comes when I can’t remember what function does what, I figure that means I’ve lost the fight with the feeping creature. I’m not entirely convinced of the wisdom of this, but it’s been nothing but fun so far.
Your ability to use or enjoy honk is likely a function of the extent to which your attitudes about social media conform to mine. And your ability to tolerate frustrating design choices.
Future updates will be announced at honk.tedunangst.com until they are not.