Archives

Tags

Posts with tag "activitypub"

Spritely website launches, plus APConf video(s)!

By Christopher Lemmer Webber on Wed 30 September 2020

Note: This originally appeared as a post on my Patreon account... thanks to all who have donated to support my work!

Hello, hello! Spritely's website has finally launched! Whew... it's been a lot of work to get it to this state! Plus check out our new logo:

Spritely logo

Not bad, eh? Also with plenty of cute characters on the Spritely site (thank you to David Revoy for taking my loose character sketches and making them into such beautiful paintings!)

But those cute characters are there for a reason! Spritely is quite ambitious and has quite a few subprojects. Here's a video that explains how they all fit together. Hopefully that makes things more clear!

Actually that video is from ActivityPub Conference 2020, the talks of which have now all have their videos live! I also moderated the intro keynote panel about ActivityPub authors/editors. Plus there's an easter egg, the ActivityPub Conference Opening Song! :)

But I can't take credit for APConf 2020... organization and support are thanks to Morgan Lemmer-Webber, Sebastian Lasse, and FOSSHost for hosting the website and BigBlueButton instance and conf.tube for generously hosting all the videos. There's a panel about the organization of APConf you can watch if you're interested in more of that! (And of course, all the other great videos too!)

So... what about that week I was going to work on Terminal Phase? Well... I'm still planning on doing it but admittedly it hasn't happened yet. All of the above took more time than expected. However, today I am working on my talk about Spritely Goblins for RacketCon, and as it turns out, extending Terminal Phase is a big part of that talk. But I'll announce more soon when the Terminal Phase stuff happens.

Onwards and upwards!

Content Addressed Vocabulary

By Christopher Lemmer Webber on Wed 26 February 2020

How can systems communicate and share meaning? Communication within systems is preceded by a form of meta-communication; we must have a sense that we mean the same things by the terms we use before we can even use them.

This is challenging enough for humans who must share meaning, but we can resolve ambiguities with context clues from a surrounding narrative. Machines, in general, need a context more explicitly laid out for them, with as little ambiguity as possible.

Standards authors of open-world systems have long struggled with such systems and have come up with some reasonable systems; unfortunately these also suffer from several pitfalls. With minimal (or sometimes none at all) adjustment to our tooling, I propose a change in how we manage ontologies.

How we deal with ambiguous terms today

Consider Note, a seemingly simple term in ActivityStreams, the vocabulary used by ActivityPub. The meaning of Note, as described by the ActivityStreams vocabulary, seems simple enough: Represents a short written work typically less than a single paragraph in length.

Here is how an ActivityStreams usage of Note might look (a bit simplified from what it would probably look like in practice):

  {"@context": "https://www.w3.org/ns/activitystreams",
   "@type": "Note",
   "content": "Would you read me a bedtime story about the great ontology wars?"}

What's that @context thing? This is some JSON-LD thing, which tries to be "more exact" about what Note we must be talking about. It does so by mapping Note to https://www.w3.org/ns/activitystreams#Note by something like the following:

  {"as": "https://www.w3.org/ns/activitystreams#",
   "Note": "as:Note",
   "content": "as:content",
   ...}

The choice to use JSON-LD has been semi-controversial in ActivityPub land; historically there was some debate about whether or not we needed to be "more exact" at all as to what terms mean. This post really isn't about JSON-LD as much as it is the more general topic of vocabularies and vocabulary mapping systems. There are other concerns people raise about JSON-LD, usually around the tooling... that's not the scope of this post. This blogpost could as easily apply to XML or Turtle or whatever; the protocol I've worked on just happens to use JSON-LD to do that, so I've used it as my illustration.

That said, the ActivityPub spec tries to make things as simple as possible for the default case of ActivityPub usage by saying that the ActivityStreams context is implied, so that if you're not doing anything complicated, so:

  {"@type": "Note",
   "content": "Would you read me a bedtime story about the great ontology wars?"}

... is really the same as the first example.

So okay, probably everyone can guess what Note means, but what about sensitive? What the heck is that? It doesn't appear in the ActivityStreams vocabulary; it kind of implies something along the lines of content-warning type behavior, like "this content may be considered sensitive" by some users, but how would you guess that just by the term? This is an extension, and it lives at http://joinmastodon.org/ns#sensitive.

So maybe if we were going to use it (and if we inline our context) it might look like:

  {"@context": {"as": "https://www.w3.org/ns/activitystreams#",
                "toot": "http://joinmastodon.org/ns#",
                "Note": "as:Note",
                "content": "as:content",
                "sensitive": "toot:sensitive"},
   "@type": "Note",
   "content": "Would you read me a bedtime story about the great ontology wars?",
   "sensitive": true}

(I mean, the Great Ontology Wars are a sensitive topic for some.)

The choice of JSON-LD in ActivityPub is controversial for various reasons. But it turns out what isn't really controversial anymore is whether we need some way of being more exact about the way we speak about terms... those who used to complain about that mostly now agree (disagreements then surround what tooling need to be used to do so (not in scope of this post), and namespace governance (in scope of this post)).

Maybe you feel like, having heard what sensitive and Note mean, these are the obvious definitions. But consider that Note itself could have meant something very different. Are we talking about a short mostly-textual post (probably on a microblog), as ActivityStreams does? Are we talking about a musical note? Are we instructing someone to take note of something, as an action (or yes, activity)?

So terms really are ambiguous, and in a decentralized but extensible system with open world assumptions, we are eventually going to result in conflicts. The choice to map our vocabulary to URIs is actually a very reasonable way to reduce ambiguity. Unfortunately, the choice to map them to namespaces and to live URIs (a-la http(s): URIs), is a mistake that will eventually bite us (and doubly so for JSON-LD contexts).

Problems appear

The first problem with choosing to put our terminology URIs at HTTP(S) URIs is that it assumes that those vocabularies will remain alive. Perhaps popular ones shall, but really the modern web rots all the time. Soon enough, many ontologies will eventually be replaced by Viagra ads.

The problem is dramatically worse for json-ld contexts (and similar documents such as XML DTDs): these are the very documents by which we map terms to their fully defined meanings. Servers get hammered by people looking up contextual mappings. This is no good already. It gets even worse when such documents add (or otherwise amend) their terminology mappings; old documents may suddenly mean different things!

(I'd be remiss to not note here that vocabulary namespaces and json-ld contexts are frequently the same URIs and yet frequently not the same thing. Still, they share a lot of the same problems and solutions in terms of liveness.)

Furthermore, both the choice to put terms in namespaces and the choice to have common contextual URIs that can change creates governance problems.

I know this from personal experience (and by that I mean many painful hours of my life wasted that I can never get back). Consider sensitive above. The Mastodon folks created their own namespace, as previously mentioned, but they didn't really want to. The good news was that the Social Web Community Group was given permission to both extend the ActivityStreams vocabulary and the official ActivityStreams context.

Despite the entire group agreeing that it made sense to make sensitive official in some way (which does not mean everyone agreed that it was a good term, just that it was in enough usage that we should make it more easily widely available), the SocialCG got tied up for months and months in meetings being unable to make progress about how to do so:

  • Should we add sensitive to the ActivityStreams namespace, or leave it in the old namespace but "officially sanction" it?
  • What is the migration path for software using the previous term URI?
  • How often should we do this? What is the governance process for incubating a new term? Should it happen in a separate namespace first and then get "pulled in" later?
  • What would happen if we didn't for terms like these, and the sites went down?
  • If we also update the json-ld context, what happens for documents that already had sensitive in them meaning either the old URI or a new one? This can have significant impact on normalization for signature verification.

The group met for months about all the topics above and came to no conclusions. Eventually we decided that no consensus could be reached, so instead no action was taken at all. What a disappointment.

In general, this seems to be common. Ironically, it leads to otherwise nice decentralized designs for vocabularies eventually ending up centralized in something like schema.org anyway.

Content addressed vocabularies (and contexts) are the answer

My friend Sandro Hawke offered a solution, which I initially rejected as terrible, decided upon further consideration was brilliant, and fully embraced. Then Sandro explained to me that I had totally misunderstood him, and that he meant something different. It turns out that I actually think my initial misunderstanding was the right answer.

Here's what I understood Sandro to say:

The name we choose for a term doesn't matter that much. What really matters is the paragraph or so of specification language that describes the term. If two implementations refer to the same specification text, they mean the same thing. So just use that as the description.

Once I (incorrectly) came to realize that this could mean naming via content addressing, I latched onto the idea. Of course! We had merely selected the wrong edge of Zooko's triangle. But we know how to fix that sort of thing.

Here's how it works. Let's remember the specification text for Note above: Represents a short written work typically less than a single paragraph in length. Let's hash that (along with a "recommendation" prefix that a user might choose to bind this to the term Note, though this is just a recommendation):

$ echo "Note: Represents a short written work typically less than a single paragraph in length." | sha256sum
3e1de3b56d2dc1bee7313963462691f9a8f46b068557b75e0e0d14c0994eddc6

So if we were defining Note via content-addressing, we instead would have defined it as urn:sha256:3e1de3b56d2dc1bee7313963462691f9a8f46b068557b75e0e0d14c0994eddc6. This is unambiguous enough to avoid collisions with other uses of the word "Note". But note that it doesn't require any servers staying up. It also doesn't have any namespace governance quagmire, because there is no namespace. Updates can be handled the usual way, via errata (translations can be handled similarly), and standards organizations can still publish such things... but it is important that the original term remain content-addressed and immutable. (Hash migration is left as an exercise for the user, with a hint that the solution is similar to that with errata.)

Anyway, our post might end up looking in the end like this instead:

  {"@context": {"Note": "urn:sha256:3e1de3b56d2dc1bee7313963462691f9a8f46b068557b75e0e0d14c0994eddc6",
                "content": "urn:sha256:57dc44a1cdcbb7aa976a65a858b4d349ad6110d58d9d546650ce2b0e2b1048e4",
                "sensitive": "urn:sha256:81d98cf83fcf733400ad5d2a25495feeea47f287193a53a9722f4cb025da88f1"},
   "@type": "Note",
   "content": "Would you read me a bedtime story about the great ontology wars?",
   "sensitive": true}

I'll note very briefly that content-addressing is also the answer for JSON-LD contexts. If something like Datashards or IPFS were used to host json-ld contexts, each post could link to the exact immutable content-addressed context it was intended to be used with. Servers that use such contexts can "pin" them to keep them available, avoiding a single point of failure (or bandwidth bottleneck).

  {"@context": "idsc:p0.JLnUcJN4R1KNvSXm9Ut3Tmg7WfXAKEOx47p01Pk_Htw.2_rCdtnEha1RpD_qyzxhFIjUvLj7crIbzpmzWei5xRk",
   "@type": "Note",
   "content": "Would you read me a bedtime story about the great ontology wars?",
   "sensitive": true}

As one other side-note, I'll also observe that even though the fully expanded version of the above message is:

  {"@type": "urn:sha256:3e1de3b56d2dc1bee7313963462691f9a8f46b068557b75e0e0d14c0994eddc6",
   "urn:sha256:57dc44a1cdcbb7aa976a65a858b4d349ad6110d58d9d546650ce2b0e2b1048e4": "Would you read me a bedtime story about the great ontology wars?",
   "urn:sha256:81d98cf83fcf733400ad5d2a25495feeea47f287193a53a9722f4cb025da88f1": true}

... we never needed to look at it that way because json-ld contexts (and systems like them) are actually petname systems.

Conclusions (and non-conclusions)

Let me clarify a claim I'm not making: we don't need to throw away the old terms for systems like ActivityStreams that are already well understood. However, going forward I do think that using content-addressing of new terms is a good idea. And in the long run, I think content-addressing of json-ld contexts and any documents like them is an absolute must (when they aren't inlined, anyway... but inlining is expensive).

If we adopted Content Addressed Vocabularies, working on vocabulary extensions to ActivityPub could be a different story. Imagine a git repository that communities can fork to work on new terms. We could have a drafts directory where people hammer out common extension terms, and when they're ready, we simply move them to the extensions directory. Since the names are merely hashes of the contents of that directory, statically generating a webpage that lists all current known and recommended extensions would be trivial. Everything could be handled in issues and PRs, and even if terms aren't merged into the main repo, that's merely a matter of lower term discoverability rather than a hinderance of application itself.

If we moved to content addressed vocabulary, we'd be more free from the perils of downtime and general web bitrot, freer from gatekeeping and governance challenges, but just as free (I'd argue even freer) to collaborate. Moving forward, I intend to ake content addressed approaches to terms I define in my systems, and I encourage you to do the same.

Updates: ActivityPub Conference, and more

By Christopher Lemmer Webber on Tue 01 October 2019

NOTE: This update also appeared on my Patreon account. If you're reading the below and it sounds like I'm doing a lot of useful work, consider becoming a patron!

Hello all! It's been a couple of months since I've gotten out an update; much has happened.

First of all, ActivityPub Conf happened and was a big success! The video team got things recorded an uploaded so you can watch talks from the event, including my keynote (the audio quality is a bit messed up on this one, the others are better) and Mark Miller's keynote. The other talks were all also very excellent; I'm not going to iterate them all here because you can already go watch them! I think you will find there are many thematic threads between the videos.

We had about 40 people at the event; the first day was spent on talks and the second day was an "unconference" where groups self-organized to discuss various topics of mutual interest. One common thread was about the kinds of directions I've been pushing for in Spritely: distributed encrypted storage (Datashards, with Serge Wroclawski leading the conversation on that), object capabilities (OcapPub), stamps, etc. It was interesting to watch from the start to the end of the unconference day; particularly, the Pleroma folks were there and gave a lot of feedback. Towards the start of the day I think there was much more skepticism, but towards the end we were hearing belief and interest that these kinds of things could and should be implemented and would be of real use to fediverse participants. Lain of Pleroma in particular expressed that it helped to realize that even though I'm presenting all these ideas, they don't need to be implemented all at once; we can take them on piecemeal, and incrementalism is a perfectly valid approach. (Also "OcapPub" sounds like a new protocol, whereas it's really just a way-to-use ActivityPub mostly as it already exists. Maybe time for a new name for that?)

Anyway, ActivityPub Conf was a massive success; thank you everyone who came and participated. It's clear after APConf to me just how much of a difference getting folks together can make. For those who couldn't make it, let's thank the video team (DeeAnn Little, Sebastian Lasse, Markus Feilner) for getting those videos up!

On the topic of Datashards, we have a website and a nice logo now (courtesy of mray, who also made the ActivityPub logo). Serge Wroclawski (co-host with myself of Libre Lounge) has been increasingly helping with the project; before ActivityPub Conference and Rebooting Web of Trust we worked to make sure both of our implementations could talk to each other (Serge's Python implementation and my Racket implementation). At RWoT we showed a demo where I "beamed" the death star plans to Serge's computer. (We used the same content storage server, I uploaded the death star plans, rendered the QR code on my laptop, Serge scanned the QR code from his laptop, downloaded the file and showed off the plans from his computer... with the storage server having no idea about the contents of the data we were storing there!) People really liked that demo; we have had conversations about whether Datashards may serve as a foundational system for some other tools being made in that space; more later. In the meanwhile, I'm happy we have two applications in two different languages successfully being able to read and write each others' immutable datashards updates; the next step is making sure that mutability works the same.

Rebooting Web of Trust was also a very interesting event; the highlight being that I am now collaborating with some great folks on a secure user interfaces paper. We are taking the existing Mastodon web user interface and retooling it to reduce risks such as phishing, and open the path for more peer to peer systems (very timely, since that's the direction we want to take things). Unfortunately the amount of work to do on the paper is rather huge; it may take a while until the paper is complete. In the meanwhile, the Petnames paper has turned out to be a pre-requisite for the secure UIs one; that paper has been nearly complete for some time so I guess I have to finish the work. I recently added some new UI mockups to it, but there is still more to do.

Now that these conferences are over, I am putting time towards Spritely's core vision again: distributed virtual worlds. The foundational layer for that is Spritely Goblins, an ocap-secure distributed programming environment on top of Racket. I really enjoy hacking on this and I am happy to get time back to working on it. A topic of discussion came up between myself and Mark Miller at Rebooting Web of Trust though; am I unnecessarily duplicating effort between myself and the Agoric folks? In particular, they are building something equivalent (and arguably more featureful) to Spritely Goblins named SwingSet. This would run on top of Javascript rather than Racket/Lisp/Scheme. I have found that in the past I have been not very happy when working with Javascript, but Mark suggested I take a look at Agoric's Jessie subset of Javascript, which Mark described as "closer to Scheme" (not syntactically, but in terms of language-cleanliness). It does seem nicer than Javascript; when I admitted to Mark that I am addicted to parenthetical syntax, Mark posed the question about whether building a parenthetical version of Jessie would be less work than reproducing all the other things that Agoric is doing. It's a good point; I don't know. I'm unhappy with the idea of pivoting, but I do feel like it's probably true that due diligence suggests I should consider it carefully. It is true at least that I would probably reach a broader userbase more quickly with the option of Javascript syntax; it's hard for me to deny that. I will probably explore it with some smaller tests of Agoric's stuff. But in the meanwhile, I currently plan to release a very small version of the game demo using the toolkit I already am building while testing Agoric's infrastructure in parallel. I suspect we'll see the first user-visible outputs of this in early 2020.

There have been four new Libre Lounge episodes since my last update. That's still quite a few episodes to listen to, but slower than we previously were updating; all the travel is to blame. However that is settling down and I think we'll be updating more frequently soon. Even so, we have been updating!

In addition to all this, I suspect there will be at least two major announcements in the coming months; stay tuned. Work has already occured on both, but I can only say so much right now.

Thanks to everyone who has supported my work. I work much more than full time in the cause of advancing user freedom; it's not easy to fund this work. I appreciate all of you who are giving what you can.

Now, back to work!

ActivityPub Conf 2019 Speakers

By Christopher Lemmer Webber on Wed 07 August 2019

Good news everyone! The speaker list for ActivityPub Conf 2019 is here! (In this document, below, but also in ODT and PDF formats.)

(Bad news everyone: registration is closed! We're now at 40 people registered to attend. However, we do aim to be posting recordings of the event afterwards if you couldn't register in time.)

But, just in case you'd rather see the list of speakers on a webpage rather than download a document, here you go:

Keynote: Mark Miller, “Architectures of Robust Openness”

Description coming soon! But we're very excited about Mark Miller keynoting.

Keynote: Christopher Lemmer Webber, “ActivityPub: past, present, future”

This talk gives an overview of ActivityPub: how did we get to this point? Where are we now? Where do we need to go? We'll paint a chart from past to a hopeful future with better privacy, richer interactions, and more security and control for our users.

Matt Baer, “Federated Blogging with WriteFreely”

We're building out one idea of what federated blogging could look like with separate ActivityPub-powered platforms, WriteFreely and Read.as -- one for writing and and one for reading. Beyond the software, we're also offering hosting services and helping new instances spring up to make community-building more accessible, and get ActivityPub-powered software into more hands. In this talk I'll go over our approach so far and where we're headed next.

Caleb James DeLisle, “The case for the unattributed message”

Despite it's significant contribution to internet culture, the archetype of the anonymous image board has been largely ignored by protocol designers. Perhaps the reason for this is because it's all too easy to conflate unattributed speech with unmoderated speech, which has shown itself to be a dead end. But as we've seen from Twitter and Facebook, putting a name on everything hasn't actually worked that well at improving the quality of discourse, but what it does do is put already marginalized people at greater risk.

What I credit as one of the biggest breakthroughs of the fediverse has been the loose federation which allows a person to choose their moderator, completely side stepping the question of undemocratic censorship vs. toxic free speech. Now I want to start a conversation about how we might marry this powerful moderation system to a forum which divorces the expression of thought from all forms of identity.

Cristina DeLisle, “OSS compliance with privacy by default and design”

Privacy is becoming more and more central in shaping the future of tech and the data protection legislation has contributed significantly to making this happen. Privacy by default and design are core principles that are fundamental to how software should be envisioned. The GDPR that came into the spotlight has a strong case to become a standard even outside European borders, influencing the way we protect personal data. However its impact might be, its implementation is still in its infancy. OSS has found itself facing the situation and one aspect which is particularly interesting on the tech side is how to incorporate the principles of privacy by default and design into the software that we build.

This talk is going to be an overview of how the GDPR has impacted FOSS communities, what do we mean by privacy by default and by design, how could we envision them applied in our OSS. It will bring examples from which we might find something interesting to learn from, regardless if we are looking at them as mistakes, best practices or just ways of doing things.

Michael Demetriou, “I don't know what I'm talking about: a newbie's introduction to ActivityPub”

I have just started my development journey in ActivityPubLand and I hope to have a first small application ready before ActivityPubConf. I was thinking that since I have close to zero experience with ActivityPub development, I could document my first month of experience, describe the onboarding process and point out useful resources and common pitfalls. In the end I can showcase what I've done during this period.

Luc Didry, “Advice to new fediverse administrators and developers”

Hosting an ActivityPub service is not like hosting another service… and it's the same for developing ActivityPub software. Here is some advice based on Framasoft's experience (we host a Mastodon instance and develop two ActivityPub software: PeerTube and Mobilizon – the last one is not yet out), errors and observations.

Maloki, “Is ActivityPub paving the way to web 3.0?”

A talk about how we're walking away from Web 2.0, and paving the way to Web 3.0 with ActivityPub development. We'll discuss what this could mean for the future of the web, we'll look at some of the history of the web, and also consider the social implications moving forward.

Pukkamustard, “The Semantic Social Network”

ActivityPub uses JSON-LD as serialization. This means @context field all over the place. But really there is more behind this: ActivityPub speaks Linked Data. In this talk we would like to show what this means and how this can be used to do cool things. We might even convince you that the Fediverse is a huge distributed graph that could be queried in very interesting ways - that the Fediverse is a Semantic Social Network.

Schmittlauch, “Decentralised Hashtag Search and Subscription in Federated Social Networks”

Hashtags have become an important tool for organising topic-related posts in all major social networks, even having managed to spark social movements like #MeToo. In federated social networks, unfortunately so far the view on all posts of a hashtag is fragmented between instances.

For a student research paper I came up with an architecture for search and subscription of hashtag-posts in federated social networks. This additional backend for instances augments the Fediverse with a little bit of P2P technology.

As this architecture is still at a conceptual stage, after presenting my work I'd like to gather ideas and feedback from various Fediverse stakeholders: What do global hashtags mean for marginalised people and moderation, are they more a tool of empowerment or of harassment? How can this concept be represented in the ActivityPub protocol? And what stories do server devs have to tell about common attack scenarios?

Serge Wroclawski, “Keeping Unwanted Messages off the Fediverse”

Spam, scams and harassment pose a threat to all social networks, including the Fediverse. In this talk, we discuss a multilayered approach to mitigating these threats. We explore spam mitigation techniques of the past as well as new techniques such as OcapPub and Postage.

Mark S. Miller keynoting at ActivityPub Conf 2019

By Christopher Lemmer Webber on Wed 24 July 2019

I am extremely pleased to announce that Mark S. Miller is keynoting at ActivityPub Conf 2019!

It's hard for me to understate how huge this is. Mark S. Miller works at Agoric which is leading the way on modern application of object capabilities, which is convenient, since exploration of how to apply object capabilities to federated social networks is a major topic of interest on the fediverse.

But just leaving it at that would be leaving out too much. We can trace Mark's work back the Agoric papers in 1988 which laid out the vision for a massive society and economy of computing agents. (And yes, that's where the Agoric company got its name from.)

For 30 years Mark has been working towards that vision, and social networks continued to intersect with its work. In the late 1990s Mark was involved in a company working on the game Electric Communities Habitat (it's hard to find information on it, but here's a rare video of it in action). (Although Mark Miller didn't work on it, Electric Communities Habitat has its predecessor in Lucasfilm's Habitat, which it turns out was a graphical multiplayer game which ran on the Commodore 64!(!!!) You can see the entertaining trailer for this game... keep in mind, this was released in 1986!)

People who have read my blog before may know that I've talked about building secure social spaces as virtual worlds: part of the reason I know it is possible is that Electric Communities Habitat for the large part built it and proved the ideas possible. Electric Communities the company did not survive, but the ideas lived on in the E programming language, which I like to describe as "the most interesting and important programming language you may have never heard of".

While the oldschool design of the website may give you the impression that the ideas there are out of date, time and time again I've found that the answers to my questions about how to build things have all been found on erights.org and in Mark Miller's dissertation.

Mark's work hasn't stopped there. Many good ideas in Javascript (such as its promises system) were largely inspired from Mark's work on the E programming language (Mark joined the standardization process of Javascript to make it be possible to build ocap-safe systems on it), and... well, I can go on and on.

Instead, I'm going to pause and say that I'm extremely excited that Mark has agreed to come to ActivityPub Conf to help introduce the community to the ideas in object capabilities. I hope the history I laid out above helps make it clear that the work to coordinate cooperative behavior amongst machines overlaps strongly with our work in the federated social web of establishing cooperative behavior amongst communities of human beings. I look forward to Mark helping us understand how to apply these ideas to our space.

Has this post got you excited? At the time of me writing this, there's still space at ActivityPub Conf 2019, and there's still time (until Monday July 29th) to submit talks. See the conference announcement for more details, and hope to see you there!

EDIT: I incorrectly cited Mark Miller originally as being involved in Lucasfilm's Habitat; fixed and better explained its history.