The GoToSocial interaction controls pattern now shows up in at least three places: basic interaction controls (#453), FEP-044f quote posts (#452), and the forthcoming FEP-7aa9 featured collections (#810).
They all need the same machinery: receive an XxxRequest, check the requester against the policy, issue an authorization or send a rejection, then let other servers verify that authorization later. The impolite path repeats too: some servers may still send bare Create, Like, or Announce activities without understanding interaction controls, and those need to be handled gracefully.
Right now, applications have to implement all of this themselves. The parts that repeat across every use case are:
- Evaluating an
interactionPolicy against an incoming actor, including collection membership resolution (followers, following, as:Public)
- Creating and serving
XxxAuthorization objects
- Building and dispatching
Accept/Reject activities with the correct shape (polite vs. impolite path, with followers-cc broadcasting for the impolite case)
- Verifying
likeAuthorization, replyAuthorization, announceAuthorization, quoteAuthorization, etc. on incoming interactions from third servers
The hard part is collection membership resolution. Whether a remote actor is in a followers or following collection cannot be decided locally—a local shortcut can wrongly accept or reject someone because the membership decision actually lives on another server. Fedify users should not have to rebuild this logic for every feature that uses interaction policies.
What should the API look like?
Possible directions
On helper functions: Export standalone functions such as evaluateInteractionPolicy(policy, actorUri, context) returning something like 'automatic' | 'manual' | 'denied', alongside helpers for building and verifying authorization objects. Application developers compose these into their own inbox handlers and decide for themselves how to store pending requests or notify users. That matches Fedify's current style: expose the protocol pieces and let applications choose storage, queues, and moderation UI.
On handler registration on Federation: Add something like .onInteractionRequest(ReplyRequest, handler) to the Federation object, analogous to existing inbox listener registration. Fedify handles routing and dispatch; the handler receives a pre-evaluated request and returns a decision. This would remove inbox-handler boilerplate, but it also forces Fedify to model the automatic/manual/pending split itself, which may not fit all use cases equally well.
On packaging: A hypothetical @fedify/interaction-policy package would need @fedify/fedify as a peer dependency regardless, since this logic is tightly coupled to Context and federation internals. Starting in core and extracting later if the surface grows large seems lower risk.
Open scope question: should this cover only policy evaluation and authorization mechanics, or also the impolite interaction handling path?
Related issues
The GoToSocial interaction controls pattern now shows up in at least three places: basic interaction controls (#453), FEP-044f quote posts (#452), and the forthcoming FEP-7aa9 featured collections (#810).
They all need the same machinery: receive an
XxxRequest, check the requester against the policy, issue an authorization or send a rejection, then let other servers verify that authorization later. The impolite path repeats too: some servers may still send bareCreate,Like, orAnnounceactivities without understanding interaction controls, and those need to be handled gracefully.Right now, applications have to implement all of this themselves. The parts that repeat across every use case are:
interactionPolicyagainst an incoming actor, including collection membership resolution (followers, following,as:Public)XxxAuthorizationobjectsAccept/Rejectactivities with the correct shape (polite vs. impolite path, with followers-cc broadcasting for the impolite case)likeAuthorization,replyAuthorization,announceAuthorization,quoteAuthorization, etc. on incoming interactions from third serversThe hard part is collection membership resolution. Whether a remote actor is in a
followersorfollowingcollection cannot be decided locally—a local shortcut can wrongly accept or reject someone because the membership decision actually lives on another server. Fedify users should not have to rebuild this logic for every feature that uses interaction policies.What should the API look like?
Possible directions
On helper functions: Export standalone functions such as
evaluateInteractionPolicy(policy, actorUri, context)returning something like'automatic' | 'manual' | 'denied', alongside helpers for building and verifying authorization objects. Application developers compose these into their own inbox handlers and decide for themselves how to store pending requests or notify users. That matches Fedify's current style: expose the protocol pieces and let applications choose storage, queues, and moderation UI.On handler registration on
Federation: Add something like.onInteractionRequest(ReplyRequest, handler)to theFederationobject, analogous to existing inbox listener registration. Fedify handles routing and dispatch; the handler receives a pre-evaluated request and returns a decision. This would remove inbox-handler boilerplate, but it also forces Fedify to model the automatic/manual/pending split itself, which may not fit all use cases equally well.On packaging: A hypothetical
@fedify/interaction-policypackage would need@fedify/fedifyas a peer dependency regardless, since this logic is tightly coupled toContextand federation internals. Starting in core and extracting later if the surface grows large seems lower risk.Open scope question: should this cover only policy evaluation and authorization mechanics, or also the impolite interaction handling path?
Related issues
FeaturedCollection,FeaturedItem,FeatureRequest,FeatureAuthorization) #810 (pending)