When the maximum values for service and quality are input, the terms service[‘good’] and quality[‘good’] are fully active at 100%. The Rule then combines them with AND, which is a minimum composition — that has no effect because they are identical. This 100% value is then passed to the Consequent term tip[‘good’], which is not cropped.
The crucial point happens here. The Consequent term, which is a triangular membership function that has significant membership area below the maximum in the output universe, is defuzzified by the centroid method. The centroid of this will never be the maximum value.
If you have the tipping problem set up, you can confirm this by the following after defining the tip
Consequent:
term = tip['high']
fuzz.defuzz(term.parent.universe, term.mf, 'centroid') # Result is 21.0
So, the actual responsive range is less than the span of the universe. While expected from the math, this is not necessarily intuitive.