After much investigation and consideration, I made a few changes. These changes only reduced the number of package relationships (edges in the graph) by 7 but the shape of the diagram now makes far more sense.
There are now fewer cyclic dependencies. ROOT (the entry-point) and interactive (the server) are now at the top, where they logically exist. Types is at the very bottom, where it should be, with utils right above that, and the other data-related packages right above that. Commands is also near the top (as they are the high-level units of functionality).
The interesting thing is that this orientation and arrangement is determined by dot, on its own.
Now, another point to mention is that I could eliminate all cyclic dependencies by moving out some other basic types and replacing direct references with interfaces. While this would be "nice", I am not sure if it accomplishes anything beyond making it less obvious what is going on when reading the source. I wonder if it may make bootstrapping or logical "ownership" relationships easier to understand, though.
Still, it is interesting to see the system from this high-level perspective and get to think about the relationships in this way.
For context, I created the dot source with "./docs/build_dot.sh src/com/jeffdisher/cacophony/ com.jeffdisher.cacophony commands data.local data.global". This script is in the Cacophony source. This image is from commit d03280850ceba14459ac71d784cb0f5f2de1f551.
The other question is how useful this exercise actually is. At least it gives structure to "cleaning up the code", since that is often directionless.
Jeff.