FEP-efda: Followable objects


slug: “efda”
authors: a a@trwnh.com
status: DRAFT
dateReceived: 2025-02-13
discussionsTo: FEP-efda: Followable objects

FEP-efda: Followable objects

Summary

ActivityStreams Vocabulary defines a Follow activity, and ActivityPub defines its side effects of manipulating a followers collection, but ActivityPub does not specify a full algorithm for how to follow something. This FEP aims to provide guidance on which objects can be followed:

  • The object MUST have a followers collection present.
  • If the object does not have an inbox, then you MAY recurse upwards through attributedTo until you find a resource with an inbox. The maximum recursion depth SHOULD be 1.

A Follow activity can then be constructed for that object and delivered to the discovered inbox. Additional requirements for the structure of the Follow activity are out-of-scope.

Requirements

In order to follow an object, we use a Follow activity. But in order to use this Follow activity, we need to know the following:

  1. What can be followed?
  2. Where do we send the Follow for that object?

At the time of writing, current software practices within the fediverse enforce a limit on what can be followed. For example, Mastodon currently limits follows to actors that can be mapped to their internal concept of “accounts”, and these “accounts” are in turn limited to being any of the five “actor types” described in AS2-Vocab: Person, Group, Organization, Application, Service.

Consequently, other software which does not have such a conceptual limit is forced to declare their actors as one of the five types, or else Mastodon users will not be able to follow their actors. ActivityPub says that there is no specified mapping between “users” and “actors”, but Mastodon’s interpretation of “actors” as “users” de facto disallows following anything but a strict subset of resources.

We may therefore express Mastodon’s requirements as follows:

  • The actor MUST have a type of any of Person, Group, Organization, Application, Service.
  • The actor MUST have an inbox where the Follow will be sent.

A proposed modified requirement and algorithm are as follows:

  • The object MUST have a followers collection present.
  • If the object does not have an inbox, then you MAY recurse upwards through attributedTo until you find a resource with an inbox. The maximum recursion depth SHOULD be 1.

Algorithm

Given an object O and a recursion limit L, a general algorithm for following it can be expressed like so:

(1) Initialize a variable INBOX.
(2) If O.followers is not present, return an error OBJECT_CANNOT_BE_FOLLOWED.
(3) If O.inbox is present, set INBOX to the referenced IRI.
(4) If INBOX is unset, then initialize a variable R whose initial value is O.
(5) While INBOX is unset:
(5.1) Check that L > 0. If false, return an error MAX_RECURSION_LIMIT.
(5.2) Dereference R.attributedTo and set the variable R to this referenced resource.
(5.3) If R.inbox is present, set INBOX to the referenced IRI.
(5.4) Set the variable L to the value L - 1.
(6) Initialize a document ACTIVITY:
(6.1) …whose actor is yourself
(6.2) …whose type is Follow
(6.3) …whose object is O
(7) Make an HTTP POST request whose target is INBOX and whose body is ACTIVITY.

Additional requirements for the ACTIVITY can be defined at a protocol level, but the exact protocol and those requirements are out-of-scope for this FEP. The scope of this FEP is limited to determining which objects can be followed, and where to send the Follow.

References

Copyright

CC0 1.0 Universal (CC0 1.0) Public Domain Dedication

To the extent possible under law, the authors of this Fediverse Enhancement Proposal have waived all copyright and related or neighboring rights to this work.

In theory, being able to follow arbitrary object could be useful in certain cases, but that blurs the line between actors and objects, and in my opinion, creates more problems than it solves. Furthermore, ActivityPub doesn’t doesn’t support this use case. According to section 6.5 Follow Activity, only actors can be followed:

The Follow activity is used to subscribe to the activities of another actor.

Again, ActivityPub (overview):

In ActivityPub, a user is represented by “actors” via the user’s accounts on servers. User’s accounts on different servers correspond to different actors.

Mastodon might be not right about hard-coding the list of actor types, but mapping users to actors is literally what specification tells us to do.

That doesn’t say the Follow activity can only be used to subscribe to the activities of another actor. The Activity Streams 2 Vocabulay is clear that Follow can be used with any object.

[The Follow activity] Indicates that the actor is “following” the object . Following is defined in the sense typically used within Social systems in which the actor is interested in any activity performed by or on the object.

IIUC, you are saying that requiring actors to only represent user accounts is too limiting. I agree that ActivityPub doesn’t require that.

From a first reading, my only mild objection to the FEP is using the followers property in the actor as a capabilities indicator, which changes its semantics a bit. I’d rather see real support for advertising capabilities.

2 Likes

Yes, this is how ActivityPub defines Follow activity. When ActivityPub describes processing of Accept activities in section 7.5 Follow Activity, it says that we are adding object actor to followers collection. followers collection is only discussed in the context of actors. Etc etc

So either this FEP is not about ActivityPub, or it re-defines Follow activity. That should be clarified in the text.

1 Like

:+1:

As I need text: The situation is complicated enough and somewhat fuzzy, let’s not make it worse.

That’s not the same as requiring the followers collection to always be associated with an actor subject (the inverse of what you referenced in the spec). What you referenced is discussing the actor of the Follow activity and what side-effects should happen when an Accept(Follow) is received. AFAICT, no one is suggesting that non-actors can perform activities.

I suppose you might claim this is a redefinition of an AP redefinition of AS2 back to the original AS2 Follow activity definition, but I’d need to think more about that. :wink:

I agree the situation (because of vague and ambiguous specs) is already complicated and fuzzy. However, I don’t think this FEP makes it any worse, unless one is arguing for the simplified Mastodon-oriented variant of ActivityPub.

mapping users to actors is fine mapping actors to users is not. the state machine works using actors as the basic unit of computation, which do not have to correspond to users.

In practice, subscribing to topics is far more useful than subscribing only to people. Limiting subscriptions only to people just causes other entities to lie and say their resources are people too. See also: the use of Group to describe things that are not groups of people.

Emphasis should be on “add the actor to the object actor's Followers Collection”, i.e. object of Follow is an actor. Yes, ActivityPub doesn’t say that object MUST always be an actor, and it doesn’t define “actor” precisely, so there is some room for interpretation, but I am not sure what such creative reading of the specification is supposed to achieve.

Standards exist to facilitate cooperation and interoperability between different vendors. Searching for new interpretations of the text does not advance that goal, and only wastes everyone’s time.

I didn’t say that subscriptions are limited to people. Actors can be organizations and applications too, and in Mastodon all actors are represented as “users” and “accounts”. This is a very reasonable decision.
A topic can be represented by application actor. This is already possible, you don’t need to re-define Follow activity for that.

Nothing is a “new interpretation”, it’s an existing pattern that interactions sometimes go to attributedTo.inbox. For example when you Like something, if it doesn’t have an object.inbox you check the object.attributedTo.inbox and send it there. What this FEP does is generalize the behavior of “crawl up attributedTo until you find an inbox”.

It’s unreasonable because actors don’t have to be users. Actors can be anything. The spec explicitly notes this. A network of actors where actors are only users is not workable because various implementers are already doing things that don’t represent users… they’re just lying and calling them users, because they have to lie in order to be compatible with the incorrect interpretations and incorrect assumptions.

Some people are against multi-typing, so there’s pushback there as well.

Multi-typing is not necessary, it can be an Application without a second type, or an object with a non-standard type but duck-typed as actor.

Anyway, there is a bigger problem. This FEP doesn't explain what "following" means if Follow.object is not an actor. ActivityPub spec says that Follow is used to subscribe to actor's activities, but what follower is supposed to receive from an object? Objects don't perform activities.

Regarding topic subscriptions, I already talked about my preferred solution in another thread. Now there is a formal proposal: https://codeberg.org/fediverse/fep/src/branch/main/fep/f06f/fep-f06f.md

Even if the spec says this, it isn’t true. Functionally and behaviorally, Follow is used to request being Added to the Follow.object.followers collection, as a side effect of when the Follow is Accepted. New activities don’t necessarily have to be addressed or delivered to that followers collection; instead, addressing and delivery is arbitrary, and the followers collection is only one possible addressee.

Activities related to that object, as decided by the attributedTo actor?

The AS2 specification describes it.

the actor is interested in any activity performed by or on the object

In the case of following a non-actor, the "on the object" is the key phrase. When some actor performs an activity on the object, that activity may be delivered to the object’s followers collection (subject to authorization, some activities may be considered private-ish).

The ActivityPub spec focuses on the “performed by the object” part, but doesn’t prohibit the “on the object”.

Note that attributedTo is not required to be an actor. AS2 says this explicitly.

Identifies one or more entities to which this object is attributed. The attributed entities might not be Actors. For instance, an object might be attributed to the completion of another activity.

I’d think any activity performed on the non-actor object by an authorized actor would be delivered to the followers collection.

EDIT: I think they have recently modified it but FunkWhale supports (or did support) following a music Library object, which is not an actor, so there is an implementation precedent for this type of behavior. IIUC, they changed, or are changing it, to be more interoperable with the Mastoverse.

We are talking about ActivityPub here. AS2 definition of Follow activity is irrelevant because followers/following collections and inboxes only exist in ActivityPub.

I think it would be a mistake to consider the AS2 vocabulary to be irrelevant to ActivityPub. A hint to the close and very relevant relationship is that the AP terms are part of the AS2 JSON-LD vocabulary.

In any case, you haven’t shown that ActivityPub prohibits the behavior described by this Follow proposal. The AS2 definitions just provide more context.

1 Like

I already provided several examples, but if that is not enough you can read the definition of Followers collection:

>Every actor SHOULD have a followers collection. This is a list of everyone who has sent a Follow activity for the actor, added as a side effect.

You gave examples and there have been objections to them and the related conclusions. By “shown”, I mean I believe you haven’t provided a solid logical argument to support your position.

I don’t think there’s any question that AP actors can have an optional followers collection.

Please quote the AP constraint that a non-actor Object is not allowed to have a followers collection or that Follow can only have an actor as an object?

I just quoted it. What part of the collection definition you don't understand?

No part? :man_shrugging: What an odd response.