Idle units wait on a los range update, which only happens when units enter or leave the range. The problem with the hold ground stance is that it then does some tests which might fail.
UnitAI.prototype.AttackEntityInZone = function(ents) { var target = ents.find(target => this.CanAttack(target) && this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true)) && (this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target)) ); if (!target) return false;
Then if a potential target is ignored because e.g. the target isn't in vision range, then it doesn't matter if the target gets closer because it won't trigger another los range update and the unit will stay idle. So we probably shouldn't have distance or vision tests here, instead those should somehow be incorporated into the query. Or we need to keep track of units that failed the distance checks and setup a timer to recheck them.
Anyway, the range used in the query shouldn't be more than the unit's vision range, otherwise targets will always fail the vision check and be ignored.
Some discussion on IRC.