Is Actor a core type?
Section 4. Model lists eight core types (Object, Link, Activity, etc). It is followed by sections describing these core types in detail: 4.1 Object, 4.2 Link and then 4.3 Actor, which is not included in the list of core types.
Actor is defined as a specialization of Object, but this is also true for Activity, and yet Activity is considered a core type.
So section 4 on Model does not have subsections for each of the core types listed.
It also has subsections about other topics, including natural language values and marking up languages.
So, I don't think that having a subsection on "Actor" necessarily means that Actor is a "core type". It is a little confusing that the "Actor" subsection is right in the middle of the other type subsections!
I also think that we have a weak definition of "core type". I think right now it is just an enumeration of those 8 types, but it might also mean types in the vocabulary that don't have a parent or supertype. It might also derive from the early OWL definition for AS2.
There might also be a definitional term that "core types" are "the types described and defined in AS2 Core". "Abstract types" is probably another fair term to use.
Finally, I think to be a "core type" Actor would have to be a type at all! We don't have one defined in the context document.
Actor is a "ghost type" in the hierarchy between the Object root type and the "actor types" Person, Group, etc. I think there was a lot of conversation in the Social Web WG about whether to define an Actor type, and we eventually decided not to do it. I don't remember at this point why!
@trwnh shared the link to the discussion on this:
- https://www.w3.org/wiki/Socialwg/2015-12-15-minutes
- https://github.com/w3c/activitystreams/issues/277
I think there are a few outcomes for this ticket:
- Primer page or elsewhere defining what "core type" means besides the list of 8 types (why those 8?)
- Primer page on the "actor" types and why there is no
Actortype - Better explanation of why there is no
Actortype in the vocabulary OR - Define an
Actortype in the next version of AS
Does it matter what is a "core type"? What requirements even hinge on that definition?
Core types mentioned many times throughout the ActivityPub spec. Quick analysis:
- "actor", 124 occurrences
- "activity": 84 occurrences
- "collection": 106 occurrences
Literally everything hinges on their definitions.
Certainly, everything hangs on the definitions of the types/classes @silverpill listed (actor, activity, collection), whether or not they are core types/classes.
But how many times do the phrase "core type" or "core class" (case insensitive, perhaps with an intervening word or two, like "Core Actor Type") occur?
How much does rely on the definition(s) of "core type" or "core class", e.g., how much do the definitions of the listed types rely on the definition(s) of "core type" or "core class"?
Are the listed types really subtypes/subclasses of a "core type" or "core class"?
I can't find any normative distinction in the spec between the 8 core types and the other "core vocabulary" types (the term the spec uses for the types defined in https://www.w3.org/TR/activitystreams-vocabulary/ e.g. ones that aren't part of an extension
From this, I conclude that the idea of the "core types" is simply a pedagogical concept for explaining the spec, and maybe for structuring the spec / extension types somewhat, and otherwise has no major value to implementors. So I don't see any reason to write a Primer section on this.
Are the listed types really subtypes/subclasses of a "core type" or "core class"?
@TallTed Yes, they are. ActivityPub spec talks about the relationship to ActivityStreams in section 3. Objects:
Objects are the core concept around which both [ActivityStreams] and ActivityPub are built. Objects are often wrapped in Activities and are contained in streams of Collections, which are themselves subclasses of Objects. See the [Activity-Vocabulary] document, particularly the Core Classes; ActivityPub follows the mapping of this vocabulary very closely.
@silverpill I believe the point that @TallTed and @nightpool are making is that from an implementation perspective, it doesn't matter whether Actor is a core type because there is no requirement to alter behavior based on whether or not a type is a core type.
Nobody is disputing that the definition of e.g. Activity is important. The question is whether, since Activity is a core type, the definition of "core type" also matters (and the suggestion is that it does not).
The definition of "core type" matters because according to AS2 there is a hierarchy of types:
Every JSON object in an Activity Streams 2.0 document is either an Object or a Link. All other types defined in the Activity Vocabulary, as well as all extension types, are derived from these two base types.
Then it describes Activity and Collection core types as specializations of Object with some properties inherited from Object, and other properties unique to a subtype. For example, items property is only allowed on Collection types, and target is only allowed on Activity types.
The existence of this type hierarchy implies that different core types do not overlap. They are located on the different branches of the tree, and there can't be an Activity which is also a Collection.
If actor is not a core type, and just an Object, then it can be also a Collection or an Activity.
If actor is a core type, then it can not be a Collection or an Activity.
The definition of actor supports the latter hypothesis:
Actor objects are specializations of the base Object type that represent entities capable of carrying out an Activity.
First, it is a specialization of Object, which is how Activity and Collection core types are described. Second, if actor can be an Activity, we get an awkward situation where activities can perform other activities. Therefore, I believe that removal of Actor from the list of core types was a mistake.
There is also an inconsistency between definition of the actor (type) and the actor property:
Describes one or more entities that either performed or are expected to perform the activity.
According to the definition of "actor", it is an entity that perform activities, but "Range" of actor property is Object | Link, meaning that any object can perform activity.
The existence of this type hierarchy implies that different core types do not overlap. They are located on the different branches of the tree, and there can't be an Activity which is also a Collection.
If actor is not a core type, and just an Object, then it can be also a Collection or an Activity. If actor is a core type, then it can not be a Collection or an Activity.
no idea where you're getting this from. I don't think the spec implies this and I also don't think whether Actor is a "core type" or not has any bearing on this.
Even if I did think the specification implied that core types are non-overlapping (which I don't), it's disproven by Activity and IntransitiveActivity, which are trivially overlapping and are both defined as "core" types.
I don't think the spec implies this and I also don't think whether Actor is a "core type" or not has any bearing on this.
@nightpool If AS2 type hierarchy is modeled as a tree structure, then every element must have exactly one parent, and there can't be an object that is both Activity and Collection (two parents).
If Actor abstract type exists, and it is a subtype of Object, then it is adjacent to Activity and Collection in the hierarchy of types, and therefore there can't be an object that is both Activity and Actor (two parents).
If Actor abstract type does not exist, then any activity can also be an actor, because Activity is a subtype of Object, and actor is also an Object.
Even if I did think the specification implied that core types are non-overlapping (which I don't), it's disproven by Activity and IntransitiveActivity, which are trivially overlapping and are both defined as "core" types.
IntransitiveActivity is a subtype of Activity. Every intransitive activity is an activity, so they always overlap, but I was talking about different case (adjacent types).
It seems that in your view AS2 type hierarchy is not a tree structure, and any type can have more than one parent (more than one supertype). Am I correct?
I can't find anything in the specs that might support this view. All types in Activity Vocabulary have exactly one supertype (except Object and Link, of course, which are root types). And while the spec doesn't explicitly forbid the existence of types with two or more supertypes, it doesn't provide any guidance on how that should be interpreted or how objects with such types should be processed.
@silverpill OrderedCollectionPage is both an OrderedCollection and a CollectionPage. Furthermore, both OrderedCollection and CollectionPage are also Collection. Finally, Collection is an Object. So an OrderedCollectionPage is actually 5 types in 1: Object, Collection, OrderedCollection, CollectionPage, and OrderedCollectionPage.
OrderedCollectionPage is both an OrderedCollection and a CollectionPage
Oh, interesting. But this looks like a special case.
There is no general guidance on using multiple supertypes, and characteristics of a type which extends, for example, both Activity and Collection, are not defined.
Furthermore, both OrderedCollection and CollectionPage are also Collection. Finally, Collection is an Object. So an OrderedCollectionPage is actually 5 types in 1: Object, Collection, OrderedCollection, CollectionPage, and OrderedCollectionPage.
Those other types have only one supertype.
There is no general guidance on using multiple supertypes,
But there explicitly is?
When an implementation uses an extension type that overlaps with a core vocabulary type, the implementation MUST also specify the core vocabulary type. For instance, some vocabularies (e.g. The Good Relations Vocabulary) define their own types for describing locations. An implementation that wishes, for example, to use a http://purl.org/goodrelations/v1#Location as an object type MUST also identify the object as being a Place as illustrated in the following:
Figure 8 An Object that is both a Place and a gr:Location:
Example 8
{ "@context": [ "https://www.w3.org/ns/activitystreams", { "gr": "http://purl.org/goodrelations/v1#" } ], "type": ["Place", "gr:Location"], "name": "Sally's Restaurant", "longitude": 12.34, "latitude": 56.78, "gr:category": "restaurants/french_restaurants" }
I just think this is a standard RDF thing, you're importing assumptions from other type systems that just don't exist in RDF.
https://en.m.wikipedia.org/wiki/Colorless_green_ideas_sleep_furiously
It is syntactically valid for something to be an Activity and a Collection, and it is also schematically valid since these types are not defined as disjoint... despite that, it is semantically dubious. Semantic considerations are separate from syntactic or schematic ones. Pragmatic considerations are also separate. The pragma of an Activity also containing items is questionable, but if someone found a use case for it, then it wouldn't necessarily be invalid, even if it might not be a good idea or make much sense.
To use an example that is much clearer: it is syntactically valid for something to be both an Object and a Link, but it is schematically invalid and semantically nonsensical -- it cannot be both a real object while also being a reference to an object. We semantically distinguish between direct resources and indirect references, and then the schema enforces this distinction by defining a disjoint relation between the classes.
When looking at whether an Actor class is necessary, we find that:
- Syntactically, there is no real reason to declare that something is an Actor
- Semantically, we gain little to nothing from defining a class to represent the set of all Actors, since "anything can be an actor"
- Schematically, we could define the range of
actoras Actor, but this is an isolated statement that is only ever used to infer a tautological definition where Actor is defined as the range ofactor - Pragmatically, it might be questionably useful if it had useful semantics attached to it, but what should those semantics be? AS2 doesn't have anything to offer here, and AP perhaps loosely ties it to the "actor properties", some of which may be subject to different semantics (such as an
inboxpossibly using LDN instead of AP).
In particular, there shouldn't be so much emphasis on hierarchically defining the AS2 data model to the detriment of other technologies and specifications on which AS2 depends or can nominally interoperate with. As much as it may be ignored, AS2 uses JSON-LD as its foundation and AP uses HTTP semantics. So AS2 documents are also RDF resources and HTTP resources. General Web architecture (web-arch) should be applicable here. General concept modeling is also applicable. RDF's type system works off of composition rather than inheritance (although inheritance can be inferred via RDF Schema's subClassOf relation).
Here's a concrete example: A specific resource ("my pet cat") can be described as both a Cat and a Pet. Being a Cat allows us to infer other things (Animal, FourLeggedThing, ...) while being a Pet grants certain properties (owner, ...), but there is no need to define a PetCat class just to ensure that everything has one type only. And of course you'd be setting yourself up for fragility and lack of robustness when you encounter something that exists in a separate problem domain, like a PetCat that is also a Mayor.
If you define a MayorPetCat class, you are limiting yourself to only ever being able to communicate with peers who share exactly the same abstractions as you. Instead, if you just compose [Mayor, Pet, Cat] as three classes, then someone trying to verify pet ownership doesn't need to know that it is a cat or that it is a mayor. In fact, if you come up with a clean enough concept model, then you can infer anything with an petns:owner is a petns:Pet, by defining the rdfs:domain of petns:owner to be petns:Pet.
So the explicit type declaration becomes extraneous information if you use a duck-typing approach. But a duck-typing approach isn't feasible when the concept model isn't cleanly separated. This is a problem with certain properties in AS2 Vocab where the domain or range is Object | Link and therefore anything is possible, but this isn't the issue to discuss those properties. Focusing solely on a hypothetical Actor type, you could maybe at most say it can have followers / following / liked / etc, and probably has outbox and inbox if doing AP. But "doing AP" is such a broad notion that it doesn't meaningfully constrain the semantics of such an Actor class.
Ultimately, the question remains: why do you need an explicit Actor type to be defined and slotted into some hierarchy? What is an Actor, anyway, outside of the circular definition of "performs activities"? How would such an Actor type be used to justify its own existence?
implementation MUST also specify the core vocabulary type
@nightpool It is "type" (singular), not "types". That means there will be only one core supertype.
I just think this is a standard RDF thing, you're importing assumptions from other type systems that just don't exist in RDF.
I am not importing any assumptions, just reading the text. As far as I can tell, there are two possible interpretations of the AS2 specification:
- As a general rule, types can have only one supertype, and
OrderedCollectionPageis a special case. Then the question aboutActorbeing a core type is valid. - Types can have multiple supertypes. Any combination is valid:
CollectionandActivity,IntransitiveActivityandOrderedCollectionPage, etc. That raises other questions. How such types should be understood? How objects with multiple supertypes should be processed by implementations? And what about extended types? For example, what subtyping bothAddandRemovewould mean?
@trwnh In previous comments I mentioned several issues that might be solved by adding an Actor core type, such as activities that can perform other activities. Definition of actor is far more important for ActivityPub, but this is not what we are discussing here.
Any combination is valid [...] How such types should be understood? How objects with multiple supertypes should be processed by implementations? And what about extended types? For example, what subtyping both Add and Remove would mean?
type ie @type ie rdf:type can have multiple values (JSON-LD set, JSON array) and the way this should be processed is to use only the classes or properties you care about. If something doesn't make sense, it SHOULD be ignored.
Some of this is going to depend on processing context. If you are fetching an IRI and you want to process it as a Collection, then you check for if Collection in type (explicit typing) or if items (duck-typing). It shouldn't matter what other types are present since the processing context requires only knowing whether it is a Collection or not.
But if your processing context expects an Activity (e.g. a side-effect handler on an inbox), then you have some options to deal with what is technically undefined behavior. Semantically, [Add, Remove] would be interpreted as both Adding and Removing at the same time (unordered). Pragmatically, this could lead to one of the following outcomes, depending on protocol details:
- If the object is not in the collection, then the collection is unmodified.
- If the object is already in the collection:
- it might be removed then re-added. This might reorder the collection such that the object is now at the head of the list (having the most recent insertion time).
- it might be treated as a no-op.
Similar issues of undefined behavior arise when activities have multiple objects, and these are also protocol details. For example, "Alice created 6 objects" is a valid activity in every sense (syntactic, semantic, schematic, pragmatic), but its behavior might be undefined in the case of partial failure; this depends on whether the protocol in use declares activities to be atomic transactions or if it allows for partial success/failure.
In general, behavioral considerations come down to protocol definitions. It is the responsibility of a protocol to define its behavior in a way that is useful. Consider the ACID properties of a database. If your protocol is essentially a distributed database, then you would probably want your activities to be atomic, consistent, isolated, and durable. This might not be fully possible due to certain transactional activities being time-ordered and the separate activities arriving out-of-order, but again, it's up to a protocol to deal with those challenges.
For the purposes of AS2 as a document format, we can't make those protocol decisions at a semantic level; we can only strive to make sure that the semantics make sense. The only time an Actor type matters semantically is as the range of actor (the "circular definition" mentioned throughout). Otherwise, there's nothing we can meaningfully say about the concept of an "actor" -- it's not like anything inherits from Actor, and it's not like AS2 defines any properties attached to Actor. We'd have a more compelling argument to include a Content type that can have content.
So basically we have a few statements to add to our ontology, at most:
as:Actor a rdfs:Class.
as:Actor rdfs:subClassOf as:Object.
as:actor rdfs:range as:Actor.
But with respect to AS2-Core as a specification, the phrase "core type" could honestly be written out of the spec document and it wouldn't change anything. Such a change would be Class 2 since it doesn't affect requirements or conformance in any way. You'd still have 8 types that... don't really come with any additional considerations? The reason this GitHub issue even exists is because of the disconnect between the intro of Section 4 "Model" and the subsections 4.1 - 4.6, right? The intro describes 8 types and then the subsections describe 6 different types. There's nothing you can really conclude from that aside from it being potentially confusing. Functionally, the subsections mostly serve to provide examples of how to extend certain documents, and basically nothing else.