ServiceKey variance

Should not it be contravariant in it’s argument to match ActorRef variance?

No, because a service key is only a unique identifier for a service, a ServiceKey[A]("id1") does not have any relation to a ServiceKey[B]("id2"), so having it invariant is intentional.

The individual actors registered for it can then accept a superset of the service key type, but only register themselves as subscribers for the subset of messages represented by T, which is expressed by the ActorRef variance.