How to communicate expectations around "rabbit holes"? Without guidance, students will sometimes spend a large amount of time on a computer science assignment in a portion of the assignment that does not engage CS skills and knowledge. An example is a student who spends a lot of time creating costumes using the drawing tools in Scratch. The problem can include code, however, such as a student who has established expertise in simple conditionals but continues to build out an adventure game using repeated application of the same pattern without gaining any conceptual ground.

What practices do teachers use to successfully retain the student engagement driving a student to exert ongoing effort but redirect their effort to realize greater gains in learning skills and knowledge intended by the teacher?
There is another sort of rabbit hole, one that your best students can fall in to. I once had a situation in which students were programming with a certain library that provided a simulation - a virtual world. They had certain exercises designed to teach specific thought processes; think recursion, or design patterns, but it could be lots of things. Some of the best students figured out that they could get the right answer, not by programming within the simulation, but by re-programming the library itself to make the exercise trivial. They got the right answer by rewiring the foundation. But the intent was to help them rewire their brains. 

It is hard to condemn such students, of course. They were very clever. They learned something. But the worry is that what they learned helped them avoid learning something else that may be more important in the long run. 

In this case the solution was that I tightened up the simulator (which made it better/more secure), but I also needed to assure that they did in fact learn the lesson of the day. It isn't that they did anything wrong, or learned the wrong thing, just that they may have failed to learn something important. 

The same situation would apply if a student, asked to write a program with some hard bits, modified the compiler to make those bits easy. Good that they teach themselves something about compilers, but bad if the hard bits held some important insights that programming around them left them in the dark about. 

I sometimes have to tell a few (usually good) students that the purpose of programming exercises isn't to produce a program, but to produce learning. Usually, if I needed the program I could write a pretty good one myself.