From the Haskell '98 Report:
A data declaration may use the same field label in multiple constructors as long as the typing of the field is the same in all cases after type synonym expansion. A label cannot be shared by more than one type in scope. Field names share the top level namespace with ordinary variables and class methods and must not conflict with other top level names in scope.
I don't think there's anything more in-depth to it. As you said, the resulting field accessor has the type Pet -> String
anyway so the powers that be decided it convenient to allow you to re-use the same field name in different constructors.