--- id: spaces title: Activity that is not public, without inventing a private tier status: blocked crates: [didbot-pds, didbot-serve] dependsOn: [pds-xrpc, oauth] exitCriterion: > A record written into a Space is readable by an admitted reader, invisible to one who is not, and the canvas shows the difference. --- # spaces Private activity is done with atproto Spaces rather than an exposure tier of our own. **Gated on something outside this project.** Implementing Spaces was declined once and every fact behind that still holds: the specification calls itself a proposal, the reference implementation has not merged, and conforming costs an incremental LtHash, a deniable signature construction, three JWT types, full DPoP and a two-root CAR layout. What changed is the status — scheduled with an entry condition rather than out of scope. Until then private means federation off, which is what the local stack already does. A Space is access control, not confidentiality. ## Entry condition The specification stops saying it is a proposal, and the reference implementation merges. - [ ] **Say here when that happens**, and what it changed. - [ ] **Keep designing so records can move into a Space**. - [ ] **`com.atproto.simplespace`**, which every conforming server must serve, arrives with [pds-xrpc](pds-xrpc.md) either way. - [ ] **Say what a private record means to the index.** An admitted reader is a new kind of authority, not the same as a configured voucher. - [ ] **Policy records stay public whatever else moves.** Gating the rule makes the comparison between the rule and this server's behaviour members-only, which is the property the accountability story rests on ([policy-store](policy-store.md)). - [ ] **There is no firehose for Spaces.** Applications sync directly from hosts, so [index](index.md) needs a second path and cannot reach private activity the way it reaches public. - [ ] **This server's event stream must exclude Space records by construction**, and fail closed on a record whose membership it cannot determine. That one is a leak rather than a gap. ## Done Nothing closed yet.