diff --git a/src/applications/people/editor/PhabricatorUserEditor.php b/src/applications/people/editor/PhabricatorUserEditor.php
index c8068858da..9ab2c9d60b 100644
--- a/src/applications/people/editor/PhabricatorUserEditor.php
+++ b/src/applications/people/editor/PhabricatorUserEditor.php
@@ -1,561 +1,507 @@
 <?php
 
 /**
  * Editor class for creating and adjusting users. This class guarantees data
  * integrity and writes logs when user information changes.
  *
  * @task config     Configuration
  * @task edit       Creating and Editing Users
  * @task role       Editing Roles
  * @task email      Adding, Removing and Changing Email
  * @task internal   Internals
  */
 final class PhabricatorUserEditor extends PhabricatorEditor {
 
   private $logs = array();
 
 
 /* -(  Creating and Editing Users  )----------------------------------------- */
 
 
   /**
    * @task edit
    */
   public function createNewUser(
     PhabricatorUser $user,
     PhabricatorUserEmail $email,
     $allow_reassign = false) {
 
     if ($user->getID()) {
       throw new Exception(pht('User has already been created!'));
     }
 
     $is_reassign = false;
     if ($email->getID()) {
       if ($allow_reassign) {
         if ($email->getIsPrimary()) {
           throw new Exception(
             pht('Primary email addresses can not be reassigned.'));
         }
         $is_reassign = true;
       } else {
         throw new Exception(pht('Email has already been created!'));
       }
     }
 
     if (!PhabricatorUser::validateUsername($user->getUsername())) {
       $valid = PhabricatorUser::describeValidUsername();
       throw new Exception(pht('Username is invalid! %s', $valid));
     }
 
     // Always set a new user's email address to primary.
     $email->setIsPrimary(1);
 
     // If the primary address is already verified, also set the verified flag
     // on the user themselves.
     if ($email->getIsVerified()) {
       $user->setIsEmailVerified(1);
     }
 
     $this->willAddEmail($email);
 
     $user->openTransaction();
       try {
         $user->save();
         $email->setUserPHID($user->getPHID());
         $email->save();
       } catch (AphrontDuplicateKeyQueryException $ex) {
         // We might have written the user but failed to write the email; if
         // so, erase the IDs we attached.
         $user->setID(null);
         $user->setPHID(null);
 
         $user->killTransaction();
         throw $ex;
       }
 
-      $log = PhabricatorUserLog::initializeNewLog(
-        $this->requireActor(),
-        $user->getPHID(),
-        PhabricatorUserLog::ACTION_CREATE);
-      $log->setNewValue($email->getAddress());
-      $log->save();
-
       if ($is_reassign) {
         $log = PhabricatorUserLog::initializeNewLog(
           $this->requireActor(),
           $user->getPHID(),
           PhabricatorUserLog::ACTION_EMAIL_REASSIGN);
         $log->setNewValue($email->getAddress());
         $log->save();
       }
 
     $user->saveTransaction();
 
     if ($email->getIsVerified()) {
       $this->didVerifyEmail($user, $email);
     }
 
     return $this;
   }
 
 
-  /**
-   * @task edit
-   */
-  public function updateUser(
-    PhabricatorUser $user,
-    PhabricatorUserEmail $email = null) {
-
-    if (!$user->getID()) {
-      throw new Exception(pht('User has not been created yet!'));
-    }
-
-    $user->openTransaction();
-      $user->save();
-      if ($email) {
-        $email->save();
-      }
-
-      $log = PhabricatorUserLog::initializeNewLog(
-        $this->requireActor(),
-        $user->getPHID(),
-        PhabricatorUserLog::ACTION_EDIT);
-      $log->save();
-
-    $user->saveTransaction();
-
-    return $this;
-  }
-
-
 /* -(  Editing Roles  )------------------------------------------------------ */
 
   /**
    * @task role
    */
   public function makeSystemAgentUser(PhabricatorUser $user, $system_agent) {
     $actor = $this->requireActor();
 
     if (!$user->getID()) {
       throw new Exception(pht('User has not been created yet!'));
     }
 
     $user->openTransaction();
       $user->beginWriteLocking();
 
         $user->reload();
         if ($user->getIsSystemAgent() == $system_agent) {
           $user->endWriteLocking();
           $user->killTransaction();
           return $this;
         }
 
-        $log = PhabricatorUserLog::initializeNewLog(
-          $actor,
-          $user->getPHID(),
-          PhabricatorUserLog::ACTION_SYSTEM_AGENT);
-        $log->setOldValue($user->getIsSystemAgent());
-        $log->setNewValue($system_agent);
-
         $user->setIsSystemAgent((int)$system_agent);
         $user->save();
 
-        $log->save();
-
       $user->endWriteLocking();
     $user->saveTransaction();
 
     return $this;
   }
 
   /**
    * @task role
    */
   public function makeMailingListUser(PhabricatorUser $user, $mailing_list) {
     $actor = $this->requireActor();
 
     if (!$user->getID()) {
       throw new Exception(pht('User has not been created yet!'));
     }
 
     $user->openTransaction();
       $user->beginWriteLocking();
 
         $user->reload();
         if ($user->getIsMailingList() == $mailing_list) {
           $user->endWriteLocking();
           $user->killTransaction();
           return $this;
         }
 
-        $log = PhabricatorUserLog::initializeNewLog(
-          $actor,
-          $user->getPHID(),
-          PhabricatorUserLog::ACTION_MAILING_LIST);
-        $log->setOldValue($user->getIsMailingList());
-        $log->setNewValue($mailing_list);
-
         $user->setIsMailingList((int)$mailing_list);
         $user->save();
 
-        $log->save();
-
       $user->endWriteLocking();
     $user->saveTransaction();
 
     return $this;
   }
 
 /* -(  Adding, Removing and Changing Email  )-------------------------------- */
 
 
   /**
    * @task email
    */
   public function addEmail(
     PhabricatorUser $user,
     PhabricatorUserEmail $email) {
 
     $actor = $this->requireActor();
 
     if (!$user->getID()) {
       throw new Exception(pht('User has not been created yet!'));
     }
     if ($email->getID()) {
       throw new Exception(pht('Email has already been created!'));
     }
 
     // Use changePrimaryEmail() to change primary email.
     $email->setIsPrimary(0);
     $email->setUserPHID($user->getPHID());
 
     $this->willAddEmail($email);
 
     $user->openTransaction();
       $user->beginWriteLocking();
 
         $user->reload();
 
         try {
           $email->save();
         } catch (AphrontDuplicateKeyQueryException $ex) {
           $user->endWriteLocking();
           $user->killTransaction();
 
           throw $ex;
         }
 
         $log = PhabricatorUserLog::initializeNewLog(
           $actor,
           $user->getPHID(),
           PhabricatorUserLog::ACTION_EMAIL_ADD);
         $log->setNewValue($email->getAddress());
         $log->save();
 
       $user->endWriteLocking();
     $user->saveTransaction();
 
     // Try and match this new address against unclaimed `RepositoryIdentity`s
     PhabricatorWorker::scheduleTask(
       'PhabricatorRepositoryIdentityChangeWorker',
       array('userPHID' => $user->getPHID()),
       array('objectPHID' => $user->getPHID()));
 
     return $this;
   }
 
 
   /**
    * @task email
    */
   public function removeEmail(
     PhabricatorUser $user,
     PhabricatorUserEmail $email) {
 
     $actor = $this->requireActor();
 
     if (!$user->getID()) {
       throw new Exception(pht('User has not been created yet!'));
     }
     if (!$email->getID()) {
       throw new Exception(pht('Email has not been created yet!'));
     }
 
     $user->openTransaction();
       $user->beginWriteLocking();
 
         $user->reload();
         $email->reload();
 
         if ($email->getIsPrimary()) {
           throw new Exception(pht("Can't remove primary email!"));
         }
         if ($email->getUserPHID() != $user->getPHID()) {
           throw new Exception(pht('Email not owned by user!'));
         }
 
         $email->delete();
 
         $log = PhabricatorUserLog::initializeNewLog(
           $actor,
           $user->getPHID(),
           PhabricatorUserLog::ACTION_EMAIL_REMOVE);
         $log->setOldValue($email->getAddress());
         $log->save();
 
       $user->endWriteLocking();
     $user->saveTransaction();
 
     $this->revokePasswordResetLinks($user);
 
     return $this;
   }
 
 
   /**
    * @task email
    */
   public function changePrimaryEmail(
     PhabricatorUser $user,
     PhabricatorUserEmail $email) {
     $actor = $this->requireActor();
 
     if (!$user->getID()) {
       throw new Exception(pht('User has not been created yet!'));
     }
     if (!$email->getID()) {
       throw new Exception(pht('Email has not been created yet!'));
     }
 
     $user->openTransaction();
       $user->beginWriteLocking();
 
         $user->reload();
         $email->reload();
 
         if ($email->getUserPHID() != $user->getPHID()) {
           throw new Exception(pht('User does not own email!'));
         }
 
         if ($email->getIsPrimary()) {
           throw new Exception(pht('Email is already primary!'));
         }
 
         if (!$email->getIsVerified()) {
           throw new Exception(pht('Email is not verified!'));
         }
 
         $old_primary = $user->loadPrimaryEmail();
         if ($old_primary) {
           $old_primary->setIsPrimary(0);
           $old_primary->save();
         }
 
         $email->setIsPrimary(1);
         $email->save();
 
         // If the user doesn't have the verified flag set on their account
         // yet, set it. We've made sure the email is verified above. See
         // T12635 for discussion.
         if (!$user->getIsEmailVerified()) {
           $user->setIsEmailVerified(1);
           $user->save();
         }
 
         $log = PhabricatorUserLog::initializeNewLog(
           $actor,
           $user->getPHID(),
           PhabricatorUserLog::ACTION_EMAIL_PRIMARY);
         $log->setOldValue($old_primary ? $old_primary->getAddress() : null);
         $log->setNewValue($email->getAddress());
 
         $log->save();
 
       $user->endWriteLocking();
     $user->saveTransaction();
 
     if ($old_primary) {
       $old_primary->sendOldPrimaryEmail($user, $email);
     }
     $email->sendNewPrimaryEmail($user);
 
 
     $this->revokePasswordResetLinks($user);
 
     return $this;
   }
 
 
   /**
    * Verify a user's email address.
    *
    * This verifies an individual email address. If the address is the user's
    * primary address and their account was not previously verified, their
    * account is marked as email verified.
    *
    * @task email
    */
   public function verifyEmail(
     PhabricatorUser $user,
     PhabricatorUserEmail $email) {
     $actor = $this->requireActor();
 
     if (!$user->getID()) {
       throw new Exception(pht('User has not been created yet!'));
     }
     if (!$email->getID()) {
       throw new Exception(pht('Email has not been created yet!'));
     }
 
     $user->openTransaction();
       $user->beginWriteLocking();
 
         $user->reload();
         $email->reload();
 
         if ($email->getUserPHID() != $user->getPHID()) {
           throw new Exception(pht('User does not own email!'));
         }
 
         if (!$email->getIsVerified()) {
           $email->setIsVerified(1);
           $email->save();
 
           $log = PhabricatorUserLog::initializeNewLog(
             $actor,
             $user->getPHID(),
             PhabricatorUserLog::ACTION_EMAIL_VERIFY);
           $log->setNewValue($email->getAddress());
           $log->save();
         }
 
         if (!$user->getIsEmailVerified()) {
           // If the user just verified their primary email address, mark their
           // account as email verified.
           $user_primary = $user->loadPrimaryEmail();
           if ($user_primary->getID() == $email->getID()) {
             $user->setIsEmailVerified(1);
             $user->save();
           }
         }
 
       $user->endWriteLocking();
     $user->saveTransaction();
 
     $this->didVerifyEmail($user, $email);
   }
 
 
   /**
    * Reassign an unverified email address.
    */
   public function reassignEmail(
     PhabricatorUser $user,
     PhabricatorUserEmail $email) {
     $actor = $this->requireActor();
 
     if (!$user->getID()) {
       throw new Exception(pht('User has not been created yet!'));
     }
 
     if (!$email->getID()) {
       throw new Exception(pht('Email has not been created yet!'));
     }
 
     $user->openTransaction();
       $user->beginWriteLocking();
 
         $user->reload();
         $email->reload();
 
         $old_user = $email->getUserPHID();
 
         if ($old_user != $user->getPHID()) {
           if ($email->getIsVerified()) {
             throw new Exception(
               pht('Verified email addresses can not be reassigned.'));
           }
           if ($email->getIsPrimary()) {
             throw new Exception(
               pht('Primary email addresses can not be reassigned.'));
           }
 
           $email->setUserPHID($user->getPHID());
           $email->save();
 
           $log = PhabricatorUserLog::initializeNewLog(
             $actor,
             $user->getPHID(),
             PhabricatorUserLog::ACTION_EMAIL_REASSIGN);
           $log->setNewValue($email->getAddress());
           $log->save();
         }
 
       $user->endWriteLocking();
     $user->saveTransaction();
   }
 
 
 /* -(  Internals  )---------------------------------------------------------- */
 
 
   /**
    * @task internal
    */
   private function willAddEmail(PhabricatorUserEmail $email) {
 
     // Hard check before write to prevent creation of disallowed email
     // addresses. Normally, the application does checks and raises more
     // user friendly errors for us, but we omit the courtesy checks on some
     // pathways like administrative scripts for simplicity.
 
     if (!PhabricatorUserEmail::isValidAddress($email->getAddress())) {
       throw new Exception(PhabricatorUserEmail::describeValidAddresses());
     }
 
     if (!PhabricatorUserEmail::isAllowedAddress($email->getAddress())) {
       throw new Exception(PhabricatorUserEmail::describeAllowedAddresses());
     }
 
     $application_email = id(new PhabricatorMetaMTAApplicationEmailQuery())
       ->setViewer(PhabricatorUser::getOmnipotentUser())
       ->withAddresses(array($email->getAddress()))
       ->executeOne();
     if ($application_email) {
       throw new Exception($application_email->getInUseMessage());
     }
   }
 
   public function revokePasswordResetLinks(PhabricatorUser $user) {
     // Revoke any outstanding password reset links. If an attacker compromises
     // an account, changes the email address, and sends themselves a password
     // reset link, it could otherwise remain live for a short period of time
     // and allow them to compromise the account again later.
 
     PhabricatorAuthTemporaryToken::revokeTokens(
       $user,
       array($user->getPHID()),
       array(
         PhabricatorAuthOneTimeLoginTemporaryTokenType::TOKENTYPE,
         PhabricatorAuthPasswordResetTemporaryTokenType::TOKENTYPE,
       ));
   }
 
   private function didVerifyEmail(
     PhabricatorUser $user,
     PhabricatorUserEmail $email) {
 
     $event_type = PhabricatorEventType::TYPE_AUTH_DIDVERIFYEMAIL;
     $event_data = array(
       'user' => $user,
       'email' => $email,
     );
 
     $event = id(new PhabricatorEvent($event_type, $event_data))
       ->setUser($user);
     PhutilEventEngine::dispatchEvent($event);
   }
 
 
 }
diff --git a/src/applications/people/storage/PhabricatorUserLog.php b/src/applications/people/storage/PhabricatorUserLog.php
index 12cb4cb626..c7550ba8e5 100644
--- a/src/applications/people/storage/PhabricatorUserLog.php
+++ b/src/applications/people/storage/PhabricatorUserLog.php
@@ -1,223 +1,203 @@
 <?php
 
 final class PhabricatorUserLog extends PhabricatorUserDAO
   implements PhabricatorPolicyInterface {
 
   const ACTION_LOGIN          = 'login';
   const ACTION_LOGIN_PARTIAL  = 'login-partial';
   const ACTION_LOGIN_FULL     = 'login-full';
   const ACTION_LOGOUT         = 'logout';
   const ACTION_LOGIN_FAILURE  = 'login-fail';
   const ACTION_LOGIN_LEGALPAD = 'login-legalpad';
   const ACTION_RESET_PASSWORD = 'reset-pass';
 
-  const ACTION_CREATE         = 'create';
-  const ACTION_EDIT           = 'edit';
-
-  const ACTION_ADMIN          = 'admin';
-  const ACTION_SYSTEM_AGENT   = 'system-agent';
-  const ACTION_MAILING_LIST   = 'mailing-list';
-  const ACTION_DISABLE        = 'disable';
-  const ACTION_APPROVE        = 'approve';
-  const ACTION_DELETE         = 'delete';
-
   const ACTION_CONDUIT_CERTIFICATE = 'conduit-cert';
   const ACTION_CONDUIT_CERTIFICATE_FAILURE = 'conduit-cert-fail';
 
   const ACTION_EMAIL_PRIMARY    = 'email-primary';
   const ACTION_EMAIL_REMOVE     = 'email-remove';
   const ACTION_EMAIL_ADD        = 'email-add';
   const ACTION_EMAIL_VERIFY     = 'email-verify';
   const ACTION_EMAIL_REASSIGN   = 'email-reassign';
 
   const ACTION_CHANGE_PASSWORD  = 'change-password';
-  const ACTION_CHANGE_USERNAME  = 'change-username';
 
   const ACTION_ENTER_HISEC = 'hisec-enter';
   const ACTION_EXIT_HISEC = 'hisec-exit';
   const ACTION_FAIL_HISEC = 'hisec-fail';
 
   const ACTION_MULTI_ADD = 'multi-add';
   const ACTION_MULTI_REMOVE = 'multi-remove';
 
   protected $actorPHID;
   protected $userPHID;
   protected $action;
   protected $oldValue;
   protected $newValue;
   protected $details = array();
   protected $remoteAddr;
   protected $session;
 
   public static function getActionTypeMap() {
     return array(
       self::ACTION_LOGIN => pht('Login'),
       self::ACTION_LOGIN_PARTIAL => pht('Login: Partial Login'),
       self::ACTION_LOGIN_FULL => pht('Login: Upgrade to Full'),
       self::ACTION_LOGIN_FAILURE => pht('Login: Failure'),
       self::ACTION_LOGIN_LEGALPAD =>
         pht('Login: Signed Required Legalpad Documents'),
       self::ACTION_LOGOUT => pht('Logout'),
       self::ACTION_RESET_PASSWORD => pht('Reset Password'),
-      self::ACTION_CREATE => pht('Create Account'),
-      self::ACTION_EDIT => pht('Edit Account'),
-      self::ACTION_ADMIN => pht('Add/Remove Administrator'),
-      self::ACTION_SYSTEM_AGENT => pht('Add/Remove System Agent'),
-      self::ACTION_MAILING_LIST => pht('Add/Remove Mailing List'),
-      self::ACTION_DISABLE => pht('Enable/Disable'),
-      self::ACTION_APPROVE => pht('Approve Registration'),
-      self::ACTION_DELETE => pht('Delete User'),
       self::ACTION_CONDUIT_CERTIFICATE
         => pht('Conduit: Read Certificate'),
       self::ACTION_CONDUIT_CERTIFICATE_FAILURE
         => pht('Conduit: Read Certificate Failure'),
       self::ACTION_EMAIL_PRIMARY => pht('Email: Change Primary'),
       self::ACTION_EMAIL_ADD => pht('Email: Add Address'),
       self::ACTION_EMAIL_REMOVE => pht('Email: Remove Address'),
       self::ACTION_EMAIL_VERIFY => pht('Email: Verify'),
       self::ACTION_EMAIL_REASSIGN => pht('Email: Reassign'),
       self::ACTION_CHANGE_PASSWORD => pht('Change Password'),
-      self::ACTION_CHANGE_USERNAME => pht('Change Username'),
       self::ACTION_ENTER_HISEC => pht('Hisec: Enter'),
       self::ACTION_EXIT_HISEC => pht('Hisec: Exit'),
       self::ACTION_FAIL_HISEC => pht('Hisec: Failed Attempt'),
       self::ACTION_MULTI_ADD => pht('Multi-Factor: Add Factor'),
       self::ACTION_MULTI_REMOVE => pht('Multi-Factor: Remove Factor'),
     );
   }
 
 
   public static function initializeNewLog(
     PhabricatorUser $actor = null,
     $object_phid = null,
     $action = null) {
 
     $log = new PhabricatorUserLog();
 
     if ($actor) {
       $log->setActorPHID($actor->getPHID());
       if ($actor->hasSession()) {
         $session = $actor->getSession();
 
         // NOTE: This is a hash of the real session value, so it's safe to
         // store it directly in the logs.
         $log->setSession($session->getSessionKey());
       }
     }
 
     $log->setUserPHID((string)$object_phid);
     $log->setAction($action);
 
     $address = PhabricatorEnv::getRemoteAddress();
     if ($address) {
       $log->remoteAddr = $address->getAddress();
     } else {
       $log->remoteAddr = '';
     }
 
     return $log;
   }
 
   public static function loadRecentEventsFromThisIP($action, $timespan) {
     $address = PhabricatorEnv::getRemoteAddress();
     if (!$address) {
       return array();
     }
 
     return id(new PhabricatorUserLog())->loadAllWhere(
       'action = %s AND remoteAddr = %s AND dateCreated > %d
         ORDER BY dateCreated DESC',
       $action,
       $address->getAddress(),
       PhabricatorTime::getNow() - $timespan);
   }
 
   public function save() {
     $this->details['host'] = php_uname('n');
     $this->details['user_agent'] = AphrontRequest::getHTTPHeader('User-Agent');
 
     return parent::save();
   }
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_SERIALIZATION => array(
         'oldValue' => self::SERIALIZATION_JSON,
         'newValue' => self::SERIALIZATION_JSON,
         'details'  => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'actorPHID' => 'phid?',
         'action' => 'text64',
         'remoteAddr' => 'text64',
         'session' => 'text64?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'actorPHID' => array(
           'columns' => array('actorPHID', 'dateCreated'),
         ),
         'userPHID' => array(
           'columns' => array('userPHID', 'dateCreated'),
         ),
         'action' => array(
           'columns' => array('action', 'dateCreated'),
         ),
         'dateCreated' => array(
           'columns' => array('dateCreated'),
         ),
         'remoteAddr' => array(
           'columns' => array('remoteAddr', 'dateCreated'),
         ),
         'session' => array(
           'columns' => array('session', 'dateCreated'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return PhabricatorPolicies::POLICY_NOONE;
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     if ($viewer->getIsAdmin()) {
       return true;
     }
 
     $viewer_phid = $viewer->getPHID();
     if ($viewer_phid) {
       $user_phid = $this->getUserPHID();
       if ($viewer_phid == $user_phid) {
         return true;
       }
 
       $actor_phid = $this->getActorPHID();
       if ($viewer_phid == $actor_phid) {
         return true;
       }
     }
 
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return array(
       pht('Users can view their activity and activity that affects them.'),
       pht('Administrators can always view all activity.'),
     );
   }
 
 }
diff --git a/src/applications/people/xaction/PhabricatorUserApproveTransaction.php b/src/applications/people/xaction/PhabricatorUserApproveTransaction.php
index e458c5822c..77d58bebdf 100644
--- a/src/applications/people/xaction/PhabricatorUserApproveTransaction.php
+++ b/src/applications/people/xaction/PhabricatorUserApproveTransaction.php
@@ -1,96 +1,92 @@
 <?php
 
 final class PhabricatorUserApproveTransaction
   extends PhabricatorUserTransactionType {
 
   const TRANSACTIONTYPE = 'user.approve';
 
   public function generateOldValue($object) {
     return (bool)$object->getIsApproved();
   }
 
   public function generateNewValue($object, $value) {
     return (bool)$value;
   }
 
   public function applyInternalEffects($object, $value) {
     $object->setIsApproved((int)$value);
   }
 
   public function applyExternalEffects($object, $value) {
     $user = $object;
-    $this->newUserLog(PhabricatorUserLog::ACTION_APPROVE)
-      ->setOldValue((bool)$user->getIsApproved())
-      ->setNewValue((bool)$value)
-      ->save();
 
     $actor = $this->getActor();
     $title = pht(
       'Phabricator Account "%s" Approved',
       $user->getUsername());
 
     $body = sprintf(
       "%s\n\n  %s\n\n",
       pht(
         'Your Phabricator account (%s) has been approved by %s. You can '.
         'login here:',
         $user->getUsername(),
         $actor->getUsername()),
       PhabricatorEnv::getProductionURI('/'));
 
     $mail = id(new PhabricatorMetaMTAMail())
       ->addTos(array($user->getPHID()))
       ->addCCs(array($actor->getPHID()))
       ->setSubject('[Phabricator] '.$title)
       ->setForceDelivery(true)
       ->setBody($body)
       ->saveAndSend();
   }
 
   public function getTitle() {
     $new = $this->getNewValue();
     if ($new) {
       return pht(
         '%s approved this user.',
         $this->renderAuthor());
     } else {
       return pht(
         '%s rejected this user.',
         $this->renderAuthor());
     }
   }
 
   public function shouldHideForFeed() {
     return true;
   }
 
   public function validateTransactions($object, array $xactions) {
     $actor = $this->getActor();
     $errors = array();
 
     foreach ($xactions as $xaction) {
       $is_approved = (bool)$object->getIsApproved();
 
       if ((bool)$xaction->getNewValue() === $is_approved) {
         continue;
       }
 
       if (!$actor->getIsAdmin()) {
         $errors[] = $this->newInvalidError(
           pht('You must be an administrator to approve users.'));
       }
     }
 
     return $errors;
   }
 
   public function getRequiredCapabilities(
     $object,
     PhabricatorApplicationTransaction $xaction) {
 
     // Unlike normal user edits, approvals require admin permissions, which
     // is enforced by validateTransactions().
 
     return null;
   }
 }
diff --git a/src/applications/people/xaction/PhabricatorUserDisableTransaction.php b/src/applications/people/xaction/PhabricatorUserDisableTransaction.php
index 7a8a1c7966..f259e78ee4 100644
--- a/src/applications/people/xaction/PhabricatorUserDisableTransaction.php
+++ b/src/applications/people/xaction/PhabricatorUserDisableTransaction.php
@@ -1,79 +1,72 @@
 <?php
 
 final class PhabricatorUserDisableTransaction
   extends PhabricatorUserTransactionType {
 
   const TRANSACTIONTYPE = 'user.disable';
 
   public function generateOldValue($object) {
     return (bool)$object->getIsDisabled();
   }
 
   public function generateNewValue($object, $value) {
     return (bool)$value;
   }
 
   public function applyInternalEffects($object, $value) {
     $object->setIsDisabled((int)$value);
   }
 
-  public function applyExternalEffects($object, $value) {
-    $this->newUserLog(PhabricatorUserLog::ACTION_DISABLE)
-      ->setOldValue((bool)$object->getIsDisabled())
-      ->setNewValue((bool)$value)
-      ->save();
-  }
-
   public function getTitle() {
     $new = $this->getNewValue();
     if ($new) {
       return pht(
         '%s disabled this user.',
         $this->renderAuthor());
     } else {
       return pht(
         '%s enabled this user.',
         $this->renderAuthor());
     }
   }
 
   public function shouldHideForFeed() {
     // Don't publish feed stories about disabling users, since this can be
     // a sensitive action.
     return true;
   }
 
   public function validateTransactions($object, array $xactions) {
     $errors = array();
 
     foreach ($xactions as $xaction) {
       $is_disabled = (bool)$object->getIsDisabled();
 
       if ((bool)$xaction->getNewValue() === $is_disabled) {
         continue;
       }
 
       // You must have the "Can Disable Users" permission to disable a user.
       $this->requireApplicationCapability(
         PeopleDisableUsersCapability::CAPABILITY);
 
       if ($this->getActingAsPHID() === $object->getPHID()) {
         $errors[] = $this->newInvalidError(
           pht('You can not enable or disable your own account.'));
       }
     }
 
     return $errors;
   }
 
   public function getRequiredCapabilities(
     $object,
     PhabricatorApplicationTransaction $xaction) {
 
     // You do not need to be able to edit users to disable them. Instead, this
     // requirement is replaced with a requirement that you have the "Can
     // Disable Users" permission.
 
     return null;
   }
 }
diff --git a/src/applications/people/xaction/PhabricatorUserEmpowerTransaction.php b/src/applications/people/xaction/PhabricatorUserEmpowerTransaction.php
index 1b561d3236..5499f5d8cb 100644
--- a/src/applications/people/xaction/PhabricatorUserEmpowerTransaction.php
+++ b/src/applications/people/xaction/PhabricatorUserEmpowerTransaction.php
@@ -1,98 +1,89 @@
 <?php
 
 final class PhabricatorUserEmpowerTransaction
   extends PhabricatorUserTransactionType {
 
   const TRANSACTIONTYPE = 'user.admin';
 
   public function generateOldValue($object) {
     return (bool)$object->getIsAdmin();
   }
 
   public function generateNewValue($object, $value) {
     return (bool)$value;
   }
 
   public function applyInternalEffects($object, $value) {
     $object->setIsAdmin((int)$value);
   }
 
-  public function applyExternalEffects($object, $value) {
-    $user = $object;
-
-    $this->newUserLog(PhabricatorUserLog::ACTION_ADMIN)
-      ->setOldValue($this->getOldValue())
-      ->setNewValue($value)
-      ->save();
-  }
-
   public function validateTransactions($object, array $xactions) {
     $user = $object;
     $actor = $this->getActor();
 
     $errors = array();
     foreach ($xactions as $xaction) {
       $old = $xaction->getOldValue();
       $new = $xaction->getNewValue();
 
       if ($old === $new) {
         continue;
       }
 
       if ($user->getPHID() === $actor->getPHID()) {
         $errors[] = $this->newInvalidError(
           pht('After a time, your efforts fail. You can not adjust your own '.
               'status as an administrator.'), $xaction);
       }
 
       $is_admin = $actor->getIsAdmin();
       $is_omnipotent = $actor->isOmnipotent();
 
       if (!$is_admin && !$is_omnipotent) {
         $errors[] = $this->newInvalidError(
           pht('You must be an administrator to create administrators.'),
           $xaction);
       }
     }
 
     return $errors;
   }
 
   public function getTitle() {
     $new = $this->getNewValue();
     if ($new) {
       return pht(
         '%s empowered this user as an administrator.',
         $this->renderAuthor());
     } else {
       return pht(
         '%s defrocked this user.',
         $this->renderAuthor());
     }
   }
 
   public function getTitleForFeed() {
     $new = $this->getNewValue();
     if ($new) {
       return pht(
         '%s empowered %s as an administrator.',
         $this->renderAuthor(),
         $this->renderObject());
     } else {
       return pht(
         '%s defrocked %s.',
         $this->renderAuthor(),
         $this->renderObject());
     }
   }
 
   public function getRequiredCapabilities(
     $object,
     PhabricatorApplicationTransaction $xaction) {
 
     // Unlike normal user edits, admin promotions require admin
     // permissions, which is enforced by validateTransactions().
 
     return null;
   }
 }
diff --git a/src/applications/people/xaction/PhabricatorUserTransactionType.php b/src/applications/people/xaction/PhabricatorUserTransactionType.php
index dcd45d480e..89392fd039 100644
--- a/src/applications/people/xaction/PhabricatorUserTransactionType.php
+++ b/src/applications/people/xaction/PhabricatorUserTransactionType.php
@@ -1,13 +1,4 @@
 <?php
 
 abstract class PhabricatorUserTransactionType
-  extends PhabricatorModularTransactionType {
-
-  protected function newUserLog($action) {
-    return PhabricatorUserLog::initializeNewLog(
-      $this->getActor(),
-      $this->getObject()->getPHID(),
-      $action);
-  }
-
-}
+  extends PhabricatorModularTransactionType {}
diff --git a/src/applications/people/xaction/PhabricatorUserUsernameTransaction.php b/src/applications/people/xaction/PhabricatorUserUsernameTransaction.php
index b436b76716..338b296335 100644
--- a/src/applications/people/xaction/PhabricatorUserUsernameTransaction.php
+++ b/src/applications/people/xaction/PhabricatorUserUsernameTransaction.php
@@ -1,117 +1,112 @@
 <?php
 
 final class PhabricatorUserUsernameTransaction
   extends PhabricatorUserTransactionType {
 
   const TRANSACTIONTYPE = 'user.rename';
 
   public function generateOldValue($object) {
     return $object->getUsername();
   }
 
   public function generateNewValue($object, $value) {
     return $value;
   }
 
   public function applyInternalEffects($object, $value) {
     $object->setUsername($value);
   }
 
   public function applyExternalEffects($object, $value) {
     $actor = $this->getActor();
     $user = $object;
 
     $old_username = $this->getOldValue();
     $new_username = $this->getNewValue();
 
-    $this->newUserLog(PhabricatorUserLog::ACTION_CHANGE_USERNAME)
-      ->setOldValue($old_username)
-      ->setNewValue($new_username)
-      ->save();
-
     // The SSH key cache currently includes usernames, so dirty it. See T12554
     // for discussion.
     PhabricatorAuthSSHKeyQuery::deleteSSHKeyCache();
 
     id(new PhabricatorPeopleUsernameMailEngine())
       ->setSender($actor)
       ->setRecipient($object)
       ->setOldUsername($old_username)
       ->setNewUsername($new_username)
       ->sendMail();
   }
 
   public function getTitle() {
     return pht(
       '%s renamed this user from %s to %s.',
       $this->renderAuthor(),
       $this->renderOldValue(),
       $this->renderNewValue());
   }
 
   public function getTitleForFeed() {
     return pht(
       '%s renamed %s from %s to %s.',
       $this->renderAuthor(),
       $this->renderObject(),
       $this->renderOldValue(),
       $this->renderNewValue());
   }
 
   public function validateTransactions($object, array $xactions) {
     $actor = $this->getActor();
     $errors = array();
 
     foreach ($xactions as $xaction) {
       $new = $xaction->getNewValue();
       $old = $xaction->getOldValue();
 
       if ($old === $new) {
         continue;
       }
 
       if (!$actor->getIsAdmin()) {
         $errors[] = $this->newInvalidError(
           pht('You must be an administrator to rename users.'));
       }
 
       if (!strlen($new)) {
         $errors[] = $this->newRequiredError(
           pht('New username is required.'),  $xaction);
       } else if (!PhabricatorUser::validateUsername($new)) {
         $errors[] = $this->newInvalidError(
           PhabricatorUser::describeValidUsername(), $xaction);
       }
 
       $user = id(new PhabricatorPeopleQuery())
         ->setViewer(PhabricatorUser::getOmnipotentUser())
         ->withUsernames(array($new))
         ->executeOne();
 
       if ($user) {
         $errors[] = $this->newInvalidError(
           pht('Another user already has that username.'), $xaction);
       }
 
     }
 
     return $errors;
   }
 
   public function getRequiredCapabilities(
     $object,
     PhabricatorApplicationTransaction $xaction) {
 
     // Unlike normal user edits, renames require admin permissions, which
     // is enforced by validateTransactions().
 
     return null;
   }
 
   public function shouldTryMFA(
     $object,
     PhabricatorApplicationTransaction $xaction) {
     return true;
   }
 
 }