"in Java, X == Y is true, either when X and Y and native types and their values are the same or when X and Y are two references that are pointing to the same instance."
This is not entirely true, it is not the native types, it is the primitive types. so int==long can be done, but Integer==Long will always yield false. For this primitive type mechanism Java has Widening Primitive Conversion (http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.2)
Groovy does not follow these exact semantics. Traditionally the number 1 is in Groovy an Integer and not an int. Thus we traditionally do not have primitives at all, only native types, which would be for the integral types int, long, short, byte and BigInteger. Between those we allow conversions in terms of widening and narrowing (byte = int is allowed without cast in Groovy). So unlike what that page may suggest to you, we can neither simply call equals, not can we simply call compareTo, or something like 5==5l would be always false. Thus we have some conversion code depending on the involved types we decide if we call equals or compareTo with or without conversions. In case of 5=5l we will traditionally call https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/typehandling/LongMath.java#L49 thus it will promote the Integer to a long and then not call compareTo or equals at all.
Since Groovy 1.8 groovy supports also primitives that stay primitives (before they have been boxed on the first possible chance), so in the case of 5=5l we will do the widening in bytecode and use bytecode instructions to compare the primitive longs instead of going through NumberMath. But if you have a==b and a is an Integer 5 and b a Long 5l, then we still go through that path.
So unlike Java we have widening not only for primitive types, when we do ==. We have several conversions/actions special for GString/String, our number types, lists and maps. Only if none of these apply we call compareTo for Comparables and equals as last resort. Referential identity not used for == by us at all, unless an equals method we call does that.
I would say that makes the Groovy logic for == similar in many aspects to Java, but also very different.
Is for <=>, this is also not purely calling compareTo. Both == and <=> go through https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java#L533 the only difference being that equalityCheckOnly is true for == and false for <=>. So we have 5<=>5l return 0 for example. Part of the problem is that compareTo is not required to be defined for any value, like equals. So compareTo is allowed to throw exceptions. Thus, if we have a<=>b, and b is not an instance of the class of a, then we don't call compareTo either and instead produce a GroovyRuntimeException.
What http://docs.codehaus.org/display/GROOVY/Operator+Overloading is a simplification, maybe an oversimplification in some places.
Defining the problem for == is not easy, but let me try. Basically we want to make == sense for all primitives, for maps, lists, String, GString, Character and all normal Numbers, which are Short, Byte, Integer, Long, BigInteger, Float, Double and BigDecimal and to some extend the mix of these types. And that in the sense of a somehow equal value. Neither equals, nor compareTo can do that.
That compareTo is called for an type not included in the set above is surely a point we can discuss. But we cannot ignore the cases above.