w3c / activitystreams

Activity Streams 2.0
https://www.w3.org/TR/activitystreams-core/
Other
279 stars 61 forks source link

Q: how to determine whether an arbitrary object is a subclass of Activity? #422

Closed strugee closed 1 year ago

strugee commented 7 years ago

Please Indicate One:

Please Describe the Issue:

Over in #social we're discussing ActivityPub's Object creation without Create feature and the question came up: how can one determine whether an arbitrary AS2 Object is indeed a subclass of Activity? You could maintain a list based on the Activity Vocabulary, but this is obviously brittle and won't work for third-party verbs.

My theory is that as long as the Object has an actor property, you can reasonably assume it's an Activity, because an Activity with no actor makes no sense and AFAICT actor is inappropriate for anything else. Does that make sense to the editors? Note also that e.g. IntransitiveActivity objects won't have an object property, so even "has actor and object" isn't good enough.

evanp commented 7 years ago

I think this is a probably another good example of why that feature is a false economy.

strugee commented 7 years ago

@evanp am I to understand that there's no reliable way to do this besides the "brittle" method?

evanp commented 7 years ago

@strugee I don't know. I think that mechanism is a bad idea. I think the best you can do is do the brittle method, with possibly doing some type inferencing in JSON otherwise.

strugee commented 7 years ago

@evanp okay. Seems to me that this would be a useful thing to be able to do regardless e.g. for some sort of advanced search API, but I get it. (Although I suppose that could search based on something similar to the description and not strictly specify "things that are Activities".) I'll bring this up with Chris.

Just to make sure I'm understanding you correctly, by "type inferencing" you mean something similar to what I suggested in the issue description?

evanp commented 7 years ago

It means going into the context and figuring out what's a subclass of what.

cwebber commented 7 years ago

I've become over time a lot less of a fan of the "auto-wrap-in Create" feature, though I'm even more not a fan of requiring a Create at all... I think just-an-object could be the same as wrapping in Create, and the Create is indeed fairly artificial. The problem being discussed in a sense is a problem either way though. (And notably Jessica disagrees with me on this.)

It means going into the context and figuring out what's a subclass of what.

Not really... you're implying that you need to look at the object in "expanded form" through the context, but that's not how I do it. If you encode the type heirarchy of all known types you work with locally, then you have all the info you need. I do that, and I even have a generic methods system in all my programs that use AS2 that respect the encoded type heirarchy. So it's easy to say "Here's the implementation of generic method for Object, a fallback, but here's one for Activity, and here's one for Create and one for Update". In that case, you know that something's an Activity because you can look at the type inference (I even have an (asobj-is-a? my-object ^Activity) that you can do). You also have a method that applies to Create and Update, but say you passed in Delete, it could fall back to Activity. Standard OOP heirarchy (though I allow for composite objects in my system).

Assuming you do this, for all standard AS2 objects you can very easily know which are activities or not, or even which ones are Collections, you'll even know that an OrderedCollection is a Collection.

Extensions are more tricky; the Right Approach (TM) is to expand the json-ld object then compact to your local context when storing in your database; then you can still operate on the types you know. You probably shouldn't accept an object with a type you don't recognize in C2S for ActivityPub, and in S2S, I guess not knowing the type heirarchy won't help you too much and you may misinterpret some Activities as just-Objects, but you can't really operate on any Activity you don't have coded into your local system to handle anyway; the side effects would be meaningless anyhow.

That said, is anyone else encoding the type heirarchy system the way I am? Probably few are and will. I know that what @puckipedia does is look at whether an object has actor or attributedTo and use that to determine what's an Activity. (In a sense I think this kludge is an indication that actor and attributedTo are really being interpreted, in practice, as the same thing, to represent something along the lines of author.)

cwebber commented 7 years ago

IMO, {Create {Object}} should be optional for S2S, and we should drop the auto-wrap-in-Create for C2S. will make a lot of lives easier, even though it'll make some sentences just nouns :)

gobengo commented 6 years ago

I think just-an-object could be the same as wrapping in Create, and the Create is indeed fairly artificial.

I thought the same when first read AP draft a few years ago, and tried to bring it up in Dec 2014(?) at Mozilla. To me, Create activities are just like the stored result of an HTTP endpoint being sent an object. Good to hear your thoughts on this.

If you encode the type heirarchy of all known types you work with locally, then you have all the info you need.

I do this too.

export const activitySubtypes = [
  'Accept', 'Add', 'Announce', 'Arrive', 'Block', 'Create', 'Delete',
  'Dislike', 'Flag', 'Follow', 'Ignore', 'Invite', 'Join', 'Leave', 'Like',
  'Listen', 'Move', 'Offer', 'Question', 'Reject', 'Read', 'Remove',
  'TentativeReject', 'TentativeAccept', 'Travel', 'Undo', 'Update', 'View'
]
export const isActivity = (activity: any): activity is Activity => {
  if (typeof activity === 'object') {
    return activitySubtypes.includes(activity.type)
  }
  return false
}

If I wanted to support objects using subclasses of Activity that are not in AS2 (extension/LD types), then I assume activity.type would be a string that is a URL. I would try to fetch the URL as LD, and look for a rdfs:subClassOf path that led back to as:Activity within a capped number of hops/fetches.

But @cwebber I think even your last comment answers the issue here. Let's close it?

evanp commented 1 year ago

I'm going to document these procedures for determining if an AS2 object is an Activity here:

https://www.w3.org/wiki/Activity_Streams/Primer/Identifying_Activity_Objects

evanp commented 1 year ago

Wiki updated, so closing this issue.

steve-bate commented 1 year ago

Can you include an example for this suggestion on the Wiki?

I'm not a JSON-LD expert, but I'm being told by others who know more than me about it that JSON-LD contexts don't support representing subtype relationships.

EDIT: Please consider cross-linking from the Wiki back to this issue.

evanp commented 1 year ago

There's a link from here to there. I don't see the point of adding a link from the primer back to this issue, so no.