I tested this out on 5.6, but I am seeing the behavior of calling ExitState even if the task has bShouldStateChangeOnReselect = false. The ExitTask fires whenever the state leaves the active state hierarchy. So if there are intermediate states using the task, it does not register the ExitState for the transition. For example:
-Root -Claim Resource: <- contains the task that does not fire again on reselect -Move To -Use Resource -Wait Your Turn
When it transitions from Move To->Use Resource, ExitState does not fire. It does fire when going from Use Resource->Wait Your Turn. It will call to StateComplete if the transitions are using state complete/succeed/failed transitions. If you are using Event transitions, the StateCompleted method is not triggered. There may have been a change that did this as much work has been done for StateTree between 5.5 and 5.6.
For the gameplay task, I will pass this info over to a colleague on the gameplay team. I think the reasoning was to avoid possible perf hits with AddUnique by also using RemoveSwap in UGameplayTasksComponent::OnGameplayTaskDeactivated to remove all instances of the tasks inside of KnownTasks. The comments around it tell me the team is aware of possible duplicates inside the array, but I will check to see if there is more reasoning behind this implementation.