3rd party apps running their own appviews kinda makes sense but it'd be a bit weird for mutes to be per-app. I wonder if there's a plan to be able to sync private state between separate appviews run by different parties
It’s definitely a current limitation of the protocol. Private state syncing is hard when you don’t have preestablished trusted parties and/or ways to easily scope permissions for access to some kind of central private state. Wonder if your PDS could store it and selectively give access.
Paul prolly has a lot of smart ideas about it but yeah. Syncing with the PDS often for that data would probably be prohibitively expensive on the side of the PDS and/or the third party though. We solve it by having the PDS push mutes/etc to our appview directly but it’s not very clean.
yea we have some internal early writeups about a private state protocol
it's actually far simpler than public data in a way because it doesn't need to be self-certifying. it inherits it's authority by coming from a trusted party
possibly doing some smart stuff by sharing state of synced relevant private data through http headers
but the basic idea is that the pds stores private state generically (with similar collection semantics to public data) & users authorize other schema-aware services to access & apply it
but also important note that this is "private data" - ie data that is really only meaningful to the user themselves - not "selectively shared data" which is what people think of with like private twitter accounts or groups
that one's harder 😅
All I know is we definitely don’t want private data living inside the public repo even if it’s encrypted or something so we need to figure out some method of giving a PDS a way to store, query, and mutate private state for a repo in a generic and scoped manner.
Yeah, figuring out a model for syncing that private state is hard though. You can’t really have a firehose of private state since you’d basically need one per repo which wouldn’t scale. We need to think of some other scalable sync primitive for it that will make sense with not always available svcs
out of my depth here but could you do something like publishing the uri of the record without its content, so an appview knows if it's copy of the private state is up to date without needing to hit up the PDS directly, and just sync directly as needed?
I don’t think we’d want to make it transparently visible when a user makes changes to the contents of their private repo. I thought about it being included in firehouse events with its own Rev clock or something that only moves when it updates but also you only want svcs with perms to know about it
The “dumb” version in my brain is the PDS maintains a list of webhooks and permissions objects attached to them and then emits an update event or some kind of nudge to the webhook url when things change to prompt the service to scrape the new private state. Depending on how big it gets though…
Also this means the PDS would need to scale based on the number of private state listeners and needs to have complex logic to retry these hooks somehow to give at least a little best effort on making the third party service aware of the changes. Of course the third party could just scrape regularly
The key you use to lookup the private data has to also be encrypted but in such a way that authorized servers can independently recreate it by encrypting some other state that changes with very low frequency (probably at end-user request when revoking an app view’s permissions)
That would actually be neat and transparent. Some oauth2-ish permission request saying: „do you want to give this app access to your private repo content?“
And then let the user chose what they want the app to access. Maybe only mute words, maybe more….
The more permissions though the more likely the user yolos it and grants everything. That’s the problem the Android app permissions model has. And it’s hard to explain what each permission grants in plain language.
not the end the world, there's just a lot of small apps that crop up (like the ones to see your top interactions in a circle) where I'd like to scope the access wayyy down
I might have missed this suggestion in the thread, but why not just proxy all xrpc calls for routes which could be personalized (like feeds, threads or profiles) through the PDS and then remove/modify posts from the request there before serving it to the user?
@jaz.bsky.social do you have thoughts? seems like a smart way to do it.
appview would hydrate public state, pds would hydrate private state (and thus private state stays private)
We don't do this because of things like mutelists where a user could be subscribed to a mutelist that they don't own and that their PDS doesn't have. The PDS doesn't have a reasonable way to index all lists referenced by private state of repos it owns and keep them up to date.
The PDS could sync the relevant mute lists from the AppView, basically be a mini-appview with a partial view of network data relevant for its users. iirc you worked on a lexicon-specific lightweight firehose with filters, that could work well for this use case
That puts a lot more app-awareness into the PDS than we really want and requires the PDS to keep a view of the network which breaks the model of the PDS being light and cheap to operate I think.
true, so I guess the better solution would be a new "mini-personal-appview" actor in the federation architecture, and ship that as part of the default PDS
but if the personal appview ships with the PDS surely that destroys account portability in terms of new kinds of appview coming online with new lexicons
it wouldn't really part of the pds itself, what I have in mind is more like a "self-hosted bluesky package" which includes the PDS and the mini-appview
There are also cases in which we may want to use mutes inside the AppView i.e. when generating recommendations for follows and/or when generating notifications where the data that goes back doesn't necessarily proxy through the PDS. Push notifs don't hit the PDS at all right now.
I feel like letting the AppView do this many things (which could also be achieved by filtering notifs or recommendations PDS-side after the initial ones are generated by an AppView) increases the centralization risk a bit higher than would be necessary in the AT Proto architecture
I think these are known tradeoffs being made with intention to reduce the complexity and cost of operating a PDS while maintaining the user experience that 99% of users desire. There are probably ways to do mobile push notifications from a PDS but I really doubt it's going to be simple.
Hmm yeah push notifs are a harder problem. They could work by passing it AppView->PDS(mute filter)->AppView but that would leak the muted users anyways, because the AppView can just keep track of what comes back :D
But I see the argument for starting with a simpler solution (especially because we don't know the effects of third-party lexicons on the architecture yet), and it's good enough for now. And fortunately it's easy for clients to just switch their xrpc endpoint to a different URL later
Of course this adds quite a lot of complexity, but long-term it's worth it imo to keep privacy of private data and the global appviews shouldn't be stateful
the main reason to not do it this way is to get app-aware logic out of the PDS. otherwise when you make a lexicon/app change you need to update client-app, AppView, *and* wait for all the PDS instances in the ecosystem to upgrade
the goal is to make PDS selection commodity and not app-specific. it is a bummer if a new app comes out and you want to try it (full-featured), but your PDS doesn't support; and PDS hosters which do support it don't support other apps you are already using[
we aren't perfect on this right now: there is still some bsky logic for read-after-write.
some complex things that can be made generic in the future: validating Lexicons (via "resolving" Lexicon schema at runtime), blob extraction (via $type:blob at any nesting)
a similar thing comes up with labels: why not have PDS hydrate labels privately?
if you look at the label set schemas, we did in fact carve out a way to do that in a generic (Lexicon-agnostic) way, at least in theory
In addition to user lists I'd like 2 more types of lists:
1. Post lists
2. Generic string lists
1 can be used by apps to build post collections, e.g. bookmarks
2 can be used for features like mute words.