stronglyConnectedComponents
Partitions the graph into strongly connected components over main (non-test) edges using an iterative Tarjan's algorithm - safe on graphs deep enough to blow a recursive call stack. Each returned list is one component; a component of size >= 2 is a dependency cycle. Single module components (the common case) are acyclic. Self-loops are ignored.