Mezzanine is a system for making rooms in an open network. You tag a post with an opaque identifier — a random string that points without signifying — and that tag becomes a frequency. People who know the frequency find each other. People who don't, see a post. The room exists as a lens, not a container.
This has worked on Bluesky since February 2026. The constraint is that it runs on borrowed infrastructure. Mezzanine hijacks the cashtag feature. The tags are text conventions, not protocol-level objects. If Bluesky changes how cashtags work, Mezzanine breaks.
The Tangled repository was created to change that — to define Mezzanine as ATProto-native Lexicon schemas. But while working on that migration, something more interesting happened.
Three problems, three layers
Baldemoto has been developing a proposal called Composable Trust. It addresses community governance on the AT Protocol — specifically, how to define who belongs to a community and how to scope spaces within it.
Meanwhile, Daniel Holmgren from the Bluesky team has been publishing a Permissioned Data Diary series, designing "buckets" — protocol-level containers for access-controlled data on ATProto.
These three projects solve different problems at different layers:
Composable Trust answers: who belongs here?
Mezzanine answers: what are we talking about?
Buckets answer: who can read this?
They are not competing solutions. They stack.
How the stack works
Composable Trust introduces two primitives. A Roster issues credentials — self-authenticating records that certify community membership. A Venue scopes to a Roster and decides which members are welcome in a particular context.
When a Venue publishes its policy record on ATProto, that record gets a TID. That TID becomes the Venue's Mezzanine-style tag. Every post intended for that Venue carries the TID. The client handles the tagging — a user simply posts while "inside" the Venue.
This creates rooms. Not topic channels. Not algorithmic feeds. Rooms — spaces where people show up by choice, oriented toward each other's presence rather than a subject.
For public conversation, this is sufficient. The tag routes content. The credential filters who appears in the room. The room is a lens over the open network.
For private conversation, Daniel's buckets provide the walls. Each member's PDS holds a bucket whose access control list references the Roster. Valid credential plus no withdrawal record equals access. The same Venue TID tags content inside the bucket. Same routing, same room — but now with walls that only credentialed members can see through.
One continuous space with variable depth
The important design principle here is not "two kinds of posts." It is one continuous space with variable depth.
A visitor sees the public layer. A credentialed member sees the full context — public and permissioned content, unified by the same tag. The boundary between inside and outside is not a wall. It is a gradient.
This matters because hard boundaries fail in practice. Twitter/X's locked accounts draw a binary: follower or not, visible or not. The technical boundary works as specified. The failure is that human trust is not binary. Relationships shift. Screenshots leak. A hard wall, once breached, offers no graceful degradation.
The Composable Trust model gets this right. If most conversation flows in public and only some lives in buckets, a leak from the permissioned layer does not collapse the space. The public layer is still there. The room survives.
Mezzanine was designed around this principle. The tag creates a lens, not a container. What you see through the lens depends on what credentials you hold. The architecture Baldemoto proposes does not change Mezzanine's design. It extends the depth of what the lens can reveal.
Prior art
This pattern — layering visible and hidden content on the same post — already has demand on Bluesky. Skyblur implements a spoiler-text system by storing the unredacted original in a custom collection while posting the redacted version publicly. It works, but it is an app-level hack with no protocol-level access control. What Composable Trust and Mezzanine and buckets assemble is the protocol-native version of what Skyblur does by brute force.
Open questions
The architecture is not complete. Three problems remain visible:
Credential verification. In Baldemoto's design, the AppView — not the PDS — verifies Roster credentials and manages bucket ACLs. This makes the AppView a trusted third party. Credible exit is possible (communities can switch AppViews), but the trust requirement is real. For sovereign communities, the Roster operator can run their own AppView, at the cost of external auditability.
Tag leakage. If a public post carries a Venue TID, the existence of that Venue and its active members is visible to anyone. Baldemoto proposes placing Venue policy records inside community buckets, with pointer records mediating between public posts and Venue routing. The routing becomes opaque to outsiders while remaining parseable by the community AppView.
Withdrawal propagation. When a Roster publishes a credential withdrawal, the AppView propagates it — revoking access, removing the user from bucket ACLs, excluding their content from community feeds. Venues can override withdrawals within their own scope, creating a multi-layered governance model where Roster decisions apply globally but Venue decisions apply locally.
What this means for Mezzanine
Mezzanine does not need Composable Trust to function. It already works as lightweight, flat topic spaces on the open network. The same UI patterns — tabs, scoped feeds, discovery — serve both cases.
But Composable Trust gives Mezzanine depth. Without credentials, Mezzanine creates topic spaces. With credentials, Mezzanine creates social spaces — rooms where people gather not around a subject but around each other.
The tag is the same. The credential determines the depth. The room is continuous.
The conversation is happening in the open at tangled.org/moja.blue/mezzanine/issues/2. If this architecture interests you, that is where to join.
Nighthaven · March 2026