Block drush rsync command when specific alias is set as destination I already have policy.drush.inc inside my Drupal drush directory at sites/all/drush.  Also, I have a policy set to prevent sql-sync if the @staging alias is set.  Thus,

drush sql-sync @dev @staging 


will fail with the output Per sites/all/policy.drush.inc, you may never overwrite the staging database.

This was done with 

function drush_policy_sql_sync_validate($source = NULL, $destination = NULL) { 
  if ($destination == '@staging') {
    return drush_set_error('POLICY_DENY', dt('Per sites/all/policy.drush.inc, you may never overwrite the staging database.'));
  }
}


This function is working, and I want to do the same for the rsync command, so basically duplicated the function and replaced sql_sync with core_rsync as in

function drush_policy_core_rsync_validate($source = NULL, $destination = NULL){
  if ($destination == "@staging") {
    return drush_set_error("POLICY_DENY", dt("Per sites/all/policy.drush.inc, you may not sync external files to staging"));
  }
}


However, I still get the 'You will destroy data from $remote and replace with data from $local` warning when executing

drush rsync @dev:%files @staging:%files


How can I block drush rsync from executing and why does this function work for sql-sync but not `core-rsync'?
In the case of rsync, $destination is equal to @staging:%files, which is different than @staging.  drush_sitealias_evaluate_path is not called until after the validate function, and calling it twice would be slow.  You could test to see if $destination is @staging OR if it begins with @staging:.  That should work well enough for your purposes.

If you wanted your policy to depend on values set in your @staging alias, then it would be best to make Drush call drush_sitealias_evaluate_path before the validate function.  That would be a feature request, and should be done by posting an issue (or better yet, a PR) on the Drush project on GitHub.