Is there any documentation for 'safe' and 'aggressive' merge modes?
Its generally a contact with lower ID that's preserved. 

For aggressive merges, fields in conflict are retained from that of higher contact ID. In other words, for fields in conflict, value from higher ID overwrites on that of lower ID.

Preserving of contact, is due to the way dedupe queries are written. 

A. Example:
INSERT INTO dedupe (id1, id2, weight) SELECT t1.id id1, t2.id id2, 10 weight FROM civicrm_contact t1 JOIN civicrm_contact t2 USING (first_name) WHERE t1.id &lt; t2.id AND t1.first_name IS NOT NULL GROUP BY id1, id2 ON DUPLICATE KEY UPDATE weight = weight + VALUES(weight);


B. Here is the code and comment that makes it clear - https://github.com/civicrm/civicrm-core/blob/4.5/CRM/Dedupe/Merger.php#L636

However with CiviCRM v4.5 and above, you can decide the biasing (which contact to preserve) using merge hook - https://github.com/civicrm/civicrm-core/blob/4.5/CRM/Dedupe/Merger.php#L632

Here is an implementation example where a contact with maximum number of contributions is preserved - https://github.com/civicrm/civicrm-drupal/blob/7.x-4.5/civitest.module.sample#L1279

Same hook could also be used for deciding which value to preserve by playing with $conflicts variable. Here is an example that we did for one of our client - https://github.com/veda-consulting/uk.co.vedaconsulting.module.dedupe/blob/master/dedupe.php#L218