From a legal perspective, the term Zigbee-compliant is protected by the Zigbee alliance. A stack has to undergo compliance testing (costs money!), and the entity wishing to use the term Zigbee-compliant must be a member of the Zigbee Alliance (costs money!).
From a practical perspective, there is a minimum feature set of the Zigbee standard that has to be implemented in order be Zigbee compliant. The most important of these is the implementation of profiles, through which a device can advertise its feature list to other Zigbee devices. Zigbee profiles such as Home Control and Building Automation are found in the Zigbee standard. Implementation of Zigbee profiles is necessary if you want a device running a Zigbee stack from Vendor A to talk to a device running a Zigbee stack from Vendor B. However, this is not needed if all of your nodes are running the same stack, and you do not need to talk to nodes that are using stacks from different vendors. This stack does not implement Zigbee profiles. This stack does use the NWK, APS, AF frame formats from the Zigbee standard, and implements static tree routing as specified in the standard, so it does implement selected pieces of the Zigbee standard that I think are most needed for experimentation with wireless devices in educational, research, and personal use.
If Zigbee-compliant devices become common, and it becomes more desirable to be able to talk to Zigbee-compliant devices from other vendors, then more features of the Zigbee standard will be implemented in this stack.
However, because of the legal restrictions, it is doubtful that this stack will ever be Zigbee-compliant.
To experiment with a moving node, try a three-node test: coordinator, router, RFD. Program the coordinator and the router with the ping_poing_rejoin.c application, and the router with the router_app.c application. Initially, have the three nodes all on the desktop, and start the coordinator, then the RFD (will join the coordinator), and then the router (will join the coordinator). Press SW1 on the RFD to start the RFD and the coordinator pinging packets back and forth (you will see the RFD LED#1 begin to blink as packets are exchanged). Take both the router and RFD, and walk away from the coordinator by about 10 meters. Put the router down, and then continue walking with the RFD until it loses contact with the coordinator (you can tell this because the LED#1 will stop blinking). At this point, the RFD will begin to detect the packet send failures, and start issuing rejoins to try to rejoin the coordinator. When these fail, the RFD will then issue joins to try to join any router/coordinator in the vicinity. It should join the router at this point (you will know, as LED#1 will come back on and stay on once the node joins a network). At this point, press SW#1 on the RFD again, and it will start exchanging packets again, but this time, the packets are going through the router. Because of the use of tree routing, the RFD will get a new short address from the router that is different from the short address originally issued by the coordinator. Its old short address that was issued by the coordinator will not be re-used for a different node; if the RFD now goes out of range of the router, but in range of the coordinator, and attempts a rejoin, it will rejoin the coordinator as the coordinator will detect that this node is already in its host table and will issue the original short address to the RFD. This example also illustrates that your application should not rely on a particular short address value, as the short address depends on where the node is located in the network topology, and this can change if the node moves, or happens to join a router that is different from its previous network join.