Community Spaces on AT Protocol

ATProto has shown that competitive "big world" product experiences can be built on an open and interoperable network. Billions of posts are aggregated from millions of accounts on hundreds of PDS instances and synthesized into coherent views. Zeppelin and now Blacksky have shown that new indices can get off the ground by backfilling the full network from scratch. We should be able to make that process a lot easier, but indexing so much data will always require servers with big fast disks. You get great value and autonomy in return, but it is an investment.

But what about the scale-down story? Not all application experiences require gigantic global aggregations. A lot of folks prefer more focused or quieter community spaces: a more curated and sheltered place with shared norms, values, and interests.

It hasn't been explored as much, but I think ATProto can work great for these experiences. I've been mulling it over (while eating pizza, of course) and have some design ideas to share.

It's easier to think about these abstractions in the context of familiar app experiences. One obvious use case would be public discussion forums, like Reddit. Or writing clubs, where members publish short stories and get tips and feedback from others in the group.

Group Accounts as Community Space Identifiers

In an earlier entry , I compared different identifiers which could be used to anchor a community space. I increasingly think that a dedicated account (DID) is the best mechanism.

Accounts have a persistent identifier (the DID), as well as a human-meaningful name (a handle). The latter could be used to organize large numbers of spaces: a namespace of communities, maybe by region or topic. Eg, @lynx.wnba.sports.club or @sounders.mls.sports.club for fan groups.

Shared Data, Membership, and Roles

A group account can be a full-fledged atproto account, with a repository and blobs.

App-specific metadata and customization can be stored as records. So can curration policies and moderation rules.

Public membership relationships should be expressed bi-directionally. Group accounts would publish an "invite" record pointing at a user account (by DID), and the account would need to "confirm" with a record pointing at the group. Or, phrasing it the other way around, the user might publish a "join" record, and the group publishes a confirmation. This could be generalized into a more flexible "role" mechanism, where accounts have named duties or capabilities within the community.

Having roles be public isn't always a good thing: it can attract unwanted badgering and harassment. Until permissioned data is supported directly in atproto, communities could keep some metadata private in trusted servers, similar to how the Bluesky DMs feature works today. This functionality could be built into self-hostable app servers (discussed later).

Governance Patterns for Group Accounts

I think it is important for community spaces not to fall in to the "implicit feudalism" pattern. Governance and control of group accounts should be rich and flexible.

The membership and role mechanism could be used for voting, access controls, and more. Mechanisms could be implemented using public records in user repos, or in a private server. Control of the group account itself would probably be automated based on these mechanisms. Eg, instead of having administrators log in as the group account and take actions, control would be delegated to an app server, and members would authenticate to the app server from their own user accounts to propose actions. The app server would verify those actions against the rules and policies of the community before implementing them.

This is similar to how labelers and Ozone work in the network today. Labelers are service accounts, with control delegated to an instance of the Ozone server software. Moderators log in to Ozone to take actions, and Ozone can be configured with different roles and policies about which moderator accounts can take which actions. The current Ozone software is fairly hierarchical about this, but different software would implement different governance models.

Long-term control over a community would be rooted in control over the group account's DID. DID PLC allows registering multiple "rotation keys" for a single identity (with ranked precedence), but this is a pretty crude control mechanism. Control could again be delegated to a server that implements governance policies. Or cryptographic mechanisms like Shamir's secret sharing or multisig enforcement could be used to enact control policies.

There are many well-documented governance frameworks that could be adopted. I think what is missing today is just atproto-specific design and implementation work. How does one create a new group account, on some PDS, from within an app? How does a group account authenticate to an app server (eg, OAuth)? How does an authorized member account create repo records on the group account, or initiate authenticated API calls on behalf of the account? Whatever implementation and design flows emerge could be reused across app experiences.

Record Scoping and Community Hosting

Records in the atproto network are scoped by Lexicon NSID. This makes it possible to query and backfill only the records relevant to a specific application, using tools like tap .

We can scope things down further, to individual community spaces, by including metadata within records in a consistent way. Every interaction or piece of content created within a space should include a reference to the group account DID, eg in a top-level record field name space with string format did. In some cases, this is a natural part of the schema, but in others it could be redundant (eg, "like" records that reference a specific AT-URI). The benefit of consistency is to make it easy to filter for relevant records when consuming from the firehose or backfilling data. Generic tooling like tap could be extended to filter by space, or provide backfill helper APIs (listReposBySpace, similar to listReposByCollection).

This filtering makes it straightforward to self-host community spaces. Communities of up through thousands of active members should fit fine on a Raspberry Pi, or cost $5 to $20 a month for a small server. This could include a web app and basic media proxy ("CDN"). It could also include tooling for community control of the group account identity (discussed above).

Because the barrier to self-hosting is smaller, it becomes easier to experiment with alternative software implementations and extensions.

A great thing about this is that interoperation would still take place through public repo data. Larger app indices could still exist and provide access and discovery across many community spaces. Users who participate in multiple communities of the same app experience (aka, the same lexicons) could use a single app and seamlessly flip between them. As always, the same atproto account could be used across apps and spaces, or folks could choose to use separate accounts for different aspects of their life.

Labeler Scoping over Community Spaces

One of the big challenges for atproto moderation labelers in the Bluesky app experience is that there are not clear community boundaries. This makes the scope of work unclear, and it can easily feel like small teams need to moderate the entire network, which is totally overwhelming.

Community spaces provide a natural boundary: labelers can declare that they only moderate content and behavior within specific spaces. Communities could delegate moderation within a space to specific labelers, and declare that they are mandatory or enabled by default for all viewers. The group account itself could act as a labeler, with self-hosted appviews implementing basic labeling functionality out of the box (other appviews would consume and index those labels as usual).

Composability would still apply: individual accounts could still configure additional labelers on top of those declared by a community space.

Beyond moderation, the badging use case of labels could be used to complement the membership and role mechanisms with additional flair and social signals within a community.

Website at Group Account Handle Domain

Users today can set their atproto handle to their personal homepage. There is growing interest in giving every handle a customizable homepage by default: an "Atmospheric Website". We can do the same thing with group account handles.

This works particularly well for self-hosted community spaces: the handle homepage can be a public web view, and allow login (via OAuth) as a fully functional web app. Posted content gets a clean canonical URL, like https://seattle-scriblers.club/story/3me3b3rcagm22 for the writing club example. These web interfaces can be themed and customized (like tumblr), and extended with other lexicon content types (like a basic blog and about page).

This starts to sound a bit like Mastodon, where the same reply threads can be viewed on distinct community websites, but there are a couple of differences. One is that atproto account logins work consistently today (via OAuth), and it is fairly painless to log in and interact. You shouldn't need to copy a URL and paste it back into your own app or instance to "like" or "reply", you can just sign in. The other is that in a community space app experience (as opposed to microblogging), it makes more sense to have a canonical web location. The overall experience would feel more like tumblr sites with custom themes and domains, but a consistent login and auth flow.

Let's Do It

I think building out real app experiences around community spaces is one of the most important next steps for atproto. As an ecosystem, we need to expand out of the microblogging clone niche, both in terms of external perception and what the protocol and tooling are optimized for. We need to decentralize hosting, moderation, and product design. And I think community spaces could help unlock the high-context moderation that so many are looking for.