If the workbench does have special needs when accessing through a Link, it sure can create a specialized type of Link, like what I did in asm3. I implemented the core function of Link as an extension, which adds some APIs to the extended object to obtain the linked object, and optionally, the accumulated transformation of the object, and its python object.
That being said, I don't think it is necessary to have that many specialized Link as you suggested. Because it doesn't add much benefit doing so. On the contrary, it will become harder to maintain. Take Part::Feature for an example. Most of Part WB code unreasonably insist on obtaining the Shape property through a type derived from Part::Feature. It can simply be relaxed to obtain a property named Shape with type PropertyShape from any type of object, much like what Python code does. The recently introduced concept of Extension is certainly another way of handling this, but still has its limitation. Let's not forget about the possibility of accessing an object in a container, or a linked container?
I did some modification to Part WB to make it support the general version of Link. There is a new convenience function, Part.getShape(), in both C++ and Python. Any code in need of an OCC shape from some object can be changed to call this function, which can return the shape with the correct transformation, regardless of whether the input object is a Link, a Part::Feature in a container, a Part::Feature in a Linked container, a Link in a Linked container. You can even obtain a compound shape from the whole container with correct children visibility by calling this function.
My idea is that, if the workbench has a narrow requirement of its operating objects, like Part WB, a super function like Part.getShape() is the easier and cleaner way to go.