ReadonlysourceFirst colon-prefix of the GroupRef this provider handles.
Notify subscribed listeners that an owner's label-list changed.
The ContactsController's mutation verbs call this on every CRUD.
Read members. May resolve asynchronously (e.g., live Avatar lookups).
Contacts has no native role hierarchy — the list owner isn't a
"member" of their own list (they don't appear in members()),
so the projection is simply: in the materialized set → 'member';
otherwise → null. The owner's standing as the list creator is
a contacts-side concern (enforced at the verb layer + provider
privacy gate), not a coarse-role concern.
Provider contract. Concrete providers in
lib/social/providers/.membersis the canonical read;roleOfis the canonical role projection.isMemberandonChangeare optional fast-path / live-notification seams (defaults derive fromroleOfand no-op respectively).Role projection is mandatory. Every provider projects its native concept into the coarse
'owner' | 'admin' | 'member'vocabulary as best it can — even when the underlying source has no native role hierarchy (mql,contacts), the projection is "everyone in the materialized set is'member'". Surfacingnullis the "not in the group at all" signal. Sources with richer hierarchies (a future guild provider with leader / officer / member) fold their native roles into the coarse vocabulary — the contract is intentionally lossy.Writable providers add
add/remove/setRole/create/destroyon top — the managed provider has them; mql / contacts don't.