There is a working example
As discussed in comments we can use the native, built-in features, coming with UI-Router. One of them is $urlRouterProvider.deferIntercept(defer)
Disables (or enables) deferring location change interception.
If you wish to customize the behavior of syncing the URL (for example, if you wish to defer a transition but maintain the current URL), call this method at configuration time. Then, at run time, call $urlRouter.listen() after you have configured your own $locationChangeSuccess event handler.
I. step - STOP execution
So, we can define states in .config() phase
.config(['$stateProvider', '$urlRouterProvider','$locationProvider',
    function ($stateProvider, $urlRouterProvider,$locationProvider) {
        // States
        $stateProvider
          ...
          .state('parent', {
              ...
          })
          .state('parent.child', { 
              ...
          })
          ;
        
        ...
        // here we say STOP
        $urlRouterProvider.deferIntercept();
    }
])
II. step - init what needed in .run() - re-enable execution
This could be some naive example of run:
.run(['$urlRouter', '$timeout', '$state',
  function($urlRouter, $timeout, $state) {
    
    $timeout(function(){
      
      // here we turn all on again...
      $urlRouter.sync();
      $urlRouter.listen();
      
      // there could be some decision, driven by $http load
      // we just use some state as default target
      $state.go("parent.child");
    }, 1000)
    
}]);
Se do wait for a second and then we do re-enable all the execution and redirect to "parent.childd" ... but could be any other, based on some decision done in .run() phase
Check it here