Decorators are defined at the object's type e.g. in your example for object jane, the descriptor referred by name must be defined at the type of jane i.e. on the body of class Person. So in the case of a class, the descriptor needs to be defined at the metaclass of the class (as a class is an instance of its metaclass) to have the descriptor invoked for the given attribute lookup on the class object.
In your example, jane.name and jane.name = 'Janny' worked as the descriptor referred by name is defined at the body of class Person i.e. it exists on the Person.__dict__ (which is a mappingproxy object and is read-only). Next, Person.name found the attribute on the Person.__dict__ and saw that it has the __get__ attribute so is a descriptor hence called __get__ for retrieving value. Now, when you set Person.name = 'Jack', it sets the name attribute to refer to string object Jack via Person.__setattr__, dropping the previous reference to descriptor D. So now all references to name e.g. if you do jane.name/Person.name, you would get the string Jack.
Here's an example of how you can achieve the desired behavior by applying the descriptor at the metaclass as well:
In [15]: class FooDec:
...: def __get__(self, instance, owner=None):
...: print(f'__get__ called with: instance: {instance}, owner: {owner}')
...: def __set__(self, instance, value):
...: print(f'__set__ called with: instance: {instance}, value: {value}')
...:
In [16]: class Meta(type):
...: foo = FooDec()
...:
In [17]: class People(metaclass=Meta):
...: foo = FooDec()
...:
In [18]: People.foo
__get__ called with: instance: <class '__main__.People'>, owner: <class '__main__.Meta'>
In [19]: People.foo = 100
__set__ called with: instance: <class '__main__.People'>, value: 100
In [20]: p = People()
In [21]: p.foo
__get__ called with: instance: <__main__.People object at 0x7faa0b2cb1c0>, owner: <class '__main__.People'>
In [22]: p.foo = 1
__set__ called with: instance: <__main__.People object at 0x7faa0b2cb1c0>, value: 1