If you can obtain the ID of one of the units whose moves don't get spent, you could set a conditional breakpoint in CvUnitAI::AI_update, step into the AI_...Move subroutine, see if a missions gets pushed and, if so, how CvSelectionGroup processes that mission (startMission, continueMission). Or maybe straight away a breakpoint in those CvSelectionGroup functions (if the group ID is known) instead of bothering with CvUnitAI. If no mission is pushed and CvUnitAI::AI_update doesn't get called ... one could still check CvSelectionGroupAI::AI_update. I don't really see what could go wrong in CvPlayerAI::AI_unitUpdate itself.
I haven't changed CvPlayerAI::AI_unitUpdate() or CvSelectionGroupAI::AI_update(), but it's possible that the AI of a specific unit can fail in some way that it does not make a decision and the unit just never uses its moves.
There's BtS code for detecting when a group indefinitely fails to push a mission:
CvSelectionGroupAI::AI_update
Don't know who commented out the assertion in your codebase; doesn't seem prudent to ignore those issues. That said, the code still (silently, apart from a log entry) forces the group to finish its moves, so it's apparently not able to catch whatever bug you're dealing with. I've had an infinite loop once where a unit was not pushing a mission and also kept changing its group membership, and I
added a test to CvGame::updateMoves to identify such problems in the future. But it seems unlikely that you would've introduced a bug like this affecting both Spies and Riflemen.
Having skimmed through diffs of your CvSelectionGroup classes, the "possible loop fix" by Rhye in
CvSelectionGroup::canDoCommand, setupActionCache, canEverDoCommand, canMoveThrough, CvSelectionGroupAI::AI_seperateNonAI and AI_separateAI looks suspect. Couldn't hurt to insert assertions or breakpoints to rule out that this hack – rather than prevent an infinite loop – is hiding or even causing one.
(And I see that your mod adds loop detection in
CvSelectionGroup::groupMove. Just mentioning this for completeness' sake; this one contains an assertion - so is clearly not involved with the present problem. Oh, perhaps this supersedes the BtS loop detection, or at least most of the time, and hence the removal of the assertion in CvSelectionGroupAI::AI_update.)