diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -496,6 +496,7 @@
     'DifferentialUpdateRevisionConduitAPIMethod' => 'applications/differential/conduit/DifferentialUpdateRevisionConduitAPIMethod.php',
     'DifferentialViewPolicyField' => 'applications/differential/customfield/DifferentialViewPolicyField.php',
     'DiffusionAuditorDatasource' => 'applications/diffusion/typeahead/DiffusionAuditorDatasource.php',
+    'DiffusionAuditorFunctionDatasource' => 'applications/diffusion/typeahead/DiffusionAuditorFunctionDatasource.php',
     'DiffusionAuditorsAddAuditorsHeraldAction' => 'applications/diffusion/herald/DiffusionAuditorsAddAuditorsHeraldAction.php',
     'DiffusionAuditorsAddSelfHeraldAction' => 'applications/diffusion/herald/DiffusionAuditorsAddSelfHeraldAction.php',
     'DiffusionAuditorsHeraldAction' => 'applications/diffusion/herald/DiffusionAuditorsHeraldAction.php',
@@ -2436,6 +2437,8 @@
     'PhabricatorOwnersOwner' => 'applications/owners/storage/PhabricatorOwnersOwner.php',
     'PhabricatorOwnersPackage' => 'applications/owners/storage/PhabricatorOwnersPackage.php',
     'PhabricatorOwnersPackageDatasource' => 'applications/owners/typeahead/PhabricatorOwnersPackageDatasource.php',
+    'PhabricatorOwnersPackageFunctionDatasource' => 'applications/owners/typeahead/PhabricatorOwnersPackageFunctionDatasource.php',
+    'PhabricatorOwnersPackageOwnerDatasource' => 'applications/owners/typeahead/PhabricatorOwnersPackageOwnerDatasource.php',
     'PhabricatorOwnersPackagePHIDType' => 'applications/owners/phid/PhabricatorOwnersPackagePHIDType.php',
     'PhabricatorOwnersPackageQuery' => 'applications/owners/query/PhabricatorOwnersPackageQuery.php',
     'PhabricatorOwnersPackageSearchEngine' => 'applications/owners/query/PhabricatorOwnersPackageSearchEngine.php',
@@ -2632,6 +2635,7 @@
     'PhabricatorProjectNoProjectsDatasource' => 'applications/project/typeahead/PhabricatorProjectNoProjectsDatasource.php',
     'PhabricatorProjectObjectHasProjectEdgeType' => 'applications/project/edge/PhabricatorProjectObjectHasProjectEdgeType.php',
     'PhabricatorProjectOrUserDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserDatasource.php',
+    'PhabricatorProjectOrUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserFunctionDatasource.php',
     'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
     'PhabricatorProjectProjectHasMemberEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasMemberEdgeType.php',
     'PhabricatorProjectProjectHasObjectEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasObjectEdgeType.php',
@@ -2651,6 +2655,7 @@
     'PhabricatorProjectTransactionQuery' => 'applications/project/query/PhabricatorProjectTransactionQuery.php',
     'PhabricatorProjectUIEventListener' => 'applications/project/events/PhabricatorProjectUIEventListener.php',
     'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
+    'PhabricatorProjectUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php',
     'PhabricatorProjectViewController' => 'applications/project/controller/PhabricatorProjectViewController.php',
     'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php',
     'PhabricatorProjectsPolicyRule' => 'applications/policy/rule/PhabricatorProjectsPolicyRule.php',
@@ -4158,6 +4163,7 @@
     'DifferentialUpdateRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialViewPolicyField' => 'DifferentialCoreCustomField',
     'DiffusionAuditorDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
+    'DiffusionAuditorFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'DiffusionAuditorsAddAuditorsHeraldAction' => 'DiffusionAuditorsHeraldAction',
     'DiffusionAuditorsAddSelfHeraldAction' => 'DiffusionAuditorsHeraldAction',
     'DiffusionAuditorsHeraldAction' => 'HeraldAction',
@@ -6407,6 +6413,8 @@
       'PhabricatorApplicationTransactionInterface',
     ),
     'PhabricatorOwnersPackageDatasource' => 'PhabricatorTypeaheadDatasource',
+    'PhabricatorOwnersPackageFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
+    'PhabricatorOwnersPackageOwnerDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'PhabricatorOwnersPackagePHIDType' => 'PhabricatorPHIDType',
     'PhabricatorOwnersPackageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorOwnersPackageSearchEngine' => 'PhabricatorApplicationSearchEngine',
@@ -6650,6 +6658,7 @@
     'PhabricatorProjectNoProjectsDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorProjectObjectHasProjectEdgeType' => 'PhabricatorEdgeType',
     'PhabricatorProjectOrUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
+    'PhabricatorProjectOrUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
     'PhabricatorProjectProjectHasMemberEdgeType' => 'PhabricatorEdgeType',
     'PhabricatorProjectProjectHasObjectEdgeType' => 'PhabricatorEdgeType',
@@ -6672,6 +6681,7 @@
     'PhabricatorProjectTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorProjectUIEventListener' => 'PhabricatorEventListener',
     'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
+    'PhabricatorProjectUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'PhabricatorProjectViewController' => 'PhabricatorProjectController',
     'PhabricatorProjectWatchController' => 'PhabricatorProjectController',
     'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule',
diff --git a/src/applications/audit/application/PhabricatorAuditApplication.php b/src/applications/audit/application/PhabricatorAuditApplication.php
--- a/src/applications/audit/application/PhabricatorAuditApplication.php
+++ b/src/applications/audit/application/PhabricatorAuditApplication.php
@@ -70,9 +70,8 @@
 
     $query = id(new DiffusionCommitQuery())
       ->setViewer($user)
-      ->withAuditorPHIDs($phids)
+      ->withNeedsAuditByPHIDs($phids)
       ->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_OPEN)
-      ->withAuditAwaitingUser($user)
       ->setLimit(self::MAX_STATUS_ITEMS);
     $commits = $query->execute();
 
diff --git a/src/applications/audit/query/PhabricatorCommitSearchEngine.php b/src/applications/audit/query/PhabricatorCommitSearchEngine.php
--- a/src/applications/audit/query/PhabricatorCommitSearchEngine.php
+++ b/src/applications/audit/query/PhabricatorCommitSearchEngine.php
@@ -11,103 +11,65 @@
     return 'PhabricatorDiffusionApplication';
   }
 
-  public function buildSavedQueryFromRequest(AphrontRequest $request) {
-    $saved = new PhabricatorSavedQuery();
-
-    $saved->setParameter(
-      'auditorPHIDs',
-      $this->readPHIDsFromRequest($request, 'auditorPHIDs'));
-
-    $saved->setParameter(
-      'commitAuthorPHIDs',
-      $this->readUsersFromRequest($request, 'authors'));
-
-    $saved->setParameter(
-      'auditStatus',
-      $request->getStr('auditStatus'));
-
-    $saved->setParameter(
-      'repositoryPHIDs',
-      $this->readPHIDsFromRequest($request, 'repositoryPHIDs'));
-
-    // -- TODO - T4173 - file location
-
-    return $saved;
-  }
-
-  public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
-    $query = id(new DiffusionCommitQuery())
+  public function newQuery() {
+    return id(new DiffusionCommitQuery())
       ->needAuditRequests(true)
       ->needCommitData(true);
+  }
+
+  protected function buildQueryFromParameters(array $map) {
+    $query = $this->newQuery();
 
-    $auditor_phids = $saved->getParameter('auditorPHIDs', array());
-    if ($auditor_phids) {
-      $query->withAuditorPHIDs($auditor_phids);
+    if ($map['needsAuditByPHIDs']) {
+      $query->withNeedsAuditByPHIDs($map['needsAuditByPHIDs']);
     }
 
-    $commit_author_phids = $saved->getParameter('commitAuthorPHIDs', array());
-    if ($commit_author_phids) {
-      $query->withAuthorPHIDs($commit_author_phids);
+    if ($map['auditorPHIDs']) {
+      $query->withAuditorPHIDs($map['auditorPHIDs']);
     }
 
-    $audit_status = $saved->getParameter('auditStatus', null);
-    if ($audit_status) {
-      $query->withAuditStatus($audit_status);
+    if ($map['commitAuthorPHIDs']) {
+      $query->withAuthorPHIDs($map['commitAuthorPHIDs']);
     }
 
-    $awaiting_user_phid = $saved->getParameter('awaitingUserPHID', null);
-    if ($awaiting_user_phid) {
-      // This is used only for the built-in "needs attention" filter,
-      // so cheat and just use the already-loaded viewer rather than reloading
-      // it.
-      $query->withAuditAwaitingUser($this->requireViewer());
+    if ($map['auditStatus']) {
+      $query->withAuditStatus($map['auditStatus']);
     }
 
-    $repository_phids = $saved->getParameter('repositoryPHIDs', array());
-    if ($repository_phids) {
-      $query->withRepositoryPHIDs($repository_phids);
+    if ($map['repositoryPHIDs']) {
+      $query->withRepositoryPHIDs($map['repositoryPHIDs']);
     }
 
     return $query;
   }
 
-  public function buildSearchForm(
-    AphrontFormView $form,
-    PhabricatorSavedQuery $saved) {
-
-    $auditor_phids = $saved->getParameter('auditorPHIDs', array());
-    $commit_author_phids = $saved->getParameter(
-      'commitAuthorPHIDs',
-      array());
-    $audit_status = $saved->getParameter('auditStatus', null);
-    $repository_phids = $saved->getParameter('repositoryPHIDs', array());
-
-    $form
-      ->appendControl(
-        id(new AphrontFormTokenizerControl())
-          ->setDatasource(new DiffusionAuditorDatasource())
-          ->setName('auditorPHIDs')
-          ->setLabel(pht('Auditors'))
-          ->setValue($auditor_phids))
-      ->appendControl(
-        id(new AphrontFormTokenizerControl())
-          ->setDatasource(new PhabricatorPeopleDatasource())
-          ->setName('authors')
-          ->setLabel(pht('Commit Authors'))
-          ->setValue($commit_author_phids))
-       ->appendChild(
-         id(new AphrontFormSelectControl())
-           ->setName('auditStatus')
-           ->setLabel(pht('Audit Status'))
-           ->setOptions($this->getAuditStatusOptions())
-           ->setValue($audit_status))
-       ->appendControl(
-         id(new AphrontFormTokenizerControl())
-           ->setLabel(pht('Repositories'))
-           ->setName('repositoryPHIDs')
-           ->setDatasource(new DiffusionRepositoryDatasource())
-           ->setValue($repository_phids));
-
+  protected function buildCustomSearchFields() {
+    return array(
+      id(new PhabricatorSearchDatasourceField())
+        ->setLabel(pht('Needs Audit By'))
+        ->setKey('needsAuditByPHIDs')
+        ->setAliases(array('needs', 'need'))
+        ->setDatasource(new DiffusionAuditorFunctionDatasource()),
+      id(new PhabricatorSearchDatasourceField())
+        ->setLabel(pht('Auditors'))
+        ->setKey('auditorPHIDs')
+        ->setAliases(array('auditor', 'auditors'))
+        ->setDatasource(new DiffusionAuditorFunctionDatasource()),
+      id(new PhabricatorUsersSearchField())
+        ->setLabel(pht('Authors'))
+        ->setKey('commitAuthorPHIDs')
+        ->setAliases(array('author', 'authors')),
+      id(new PhabricatorSearchSelectField())
+        ->setLabel(pht('Audit Status'))
+        ->setKey('auditStatus')
+        ->setAliases(array('status'))
+        ->setOptions($this->getAuditStatusOptions()),
+      id(new PhabricatorSearchDatasourceField())
+        ->setLabel(pht('Repositories'))
+        ->setKey('repositoryPHIDs')
+        ->setAliases(array('repository', 'repositories'))
+        ->setDatasource(new DiffusionRepositoryDatasource()),
+    );
   }
 
   protected function getURI($path) {
@@ -118,7 +80,7 @@
     $names = array();
 
     if ($this->requireViewer()->isLoggedIn()) {
-      $names['need'] = pht('Need Attention');
+      $names['need'] = pht('Needs Audit');
       $names['problem'] = pht('Problem Commits');
     }
 
@@ -138,22 +100,24 @@
     $query->setQueryKey($query_key);
     $viewer = $this->requireViewer();
 
+    $viewer_phid = $viewer->getPHID();
+    $status_open = DiffusionCommitQuery::AUDIT_STATUS_OPEN;
+
     switch ($query_key) {
       case 'all':
         return $query;
       case 'open':
-        $query->setParameter(
-          'auditStatus',
-          DiffusionCommitQuery::AUDIT_STATUS_OPEN);
+        $query->setParameter('auditStatus', $status_open);
         return $query;
       case 'need':
-        $query->setParameter('awaitingUserPHID', $viewer->getPHID());
-        $query->setParameter(
-          'auditStatus',
-          DiffusionCommitQuery::AUDIT_STATUS_OPEN);
-        $query->setParameter(
-          'auditorPHIDs',
-          PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($viewer));
+        $needs_tokens = array(
+          $viewer_phid,
+          'projects('.$viewer_phid.')',
+          'packages('.$viewer_phid.')',
+        );
+
+        $query->setParameter('needsAuditByPHIDs', $needs_tokens);
+        $query->setParameter('auditStatus', $status_open);
         return $query;
       case 'authored':
         $query->setParameter('commitAuthorPHIDs', array($viewer->getPHID()));
diff --git a/src/applications/diffusion/query/DiffusionCommitQuery.php b/src/applications/diffusion/query/DiffusionCommitQuery.php
--- a/src/applications/diffusion/query/DiffusionCommitQuery.php
+++ b/src/applications/diffusion/query/DiffusionCommitQuery.php
@@ -15,7 +15,7 @@
   private $needAuditRequests;
   private $auditIDs;
   private $auditorPHIDs;
-  private $auditAwaitingUser;
+  private $needsAuditByPHIDs;
   private $auditStatus;
   private $epochMin;
   private $epochMax;
@@ -103,27 +103,6 @@
     return $this;
   }
 
-  /**
-   * Returns true if we should join the audit table, either because we're
-   * interested in the information if it's available or because matching rows
-   * must always have it.
-   */
-  private function shouldJoinAudits() {
-    return $this->auditStatus ||
-           $this->rowsMustHaveAudits();
-  }
-
-  /**
-   * Return true if we should `JOIN` (vs `LEFT JOIN`) the audit table, because
-   * matching commits will always have audit rows.
-   */
-  private function rowsMustHaveAudits() {
-    return
-      $this->auditIDs ||
-      $this->auditorPHIDs ||
-      $this->auditAwaitingUser;
-  }
-
   public function withAuditIDs(array $ids) {
     $this->auditIDs = $ids;
     return $this;
@@ -134,8 +113,8 @@
     return $this;
   }
 
-  public function withAuditAwaitingUser(PhabricatorUser $user) {
-    $this->auditAwaitingUser = $user;
+  public function withNeedsAuditByPHIDs(array $needs_phids) {
+    $this->needsAuditByPHIDs = $needs_phids;
     return $this;
   }
 
@@ -175,21 +154,12 @@
     }
   }
 
-  protected function loadPage() {
-    $table = new PhabricatorRepositoryCommit();
-    $conn_r = $table->establishConnection('r');
-
-    $data = queryfx_all(
-      $conn_r,
-      'SELECT commit.* FROM %T commit %Q %Q %Q %Q %Q',
-      $table->getTableName(),
-      $this->buildJoinClause($conn_r),
-      $this->buildWhereClause($conn_r),
-      $this->buildGroupClause($conn_r),
-      $this->buildOrderClause($conn_r),
-      $this->buildLimitClause($conn_r));
+  public function newResultObject() {
+    return new PhabricatorRepositoryCommit();
+  }
 
-    return $table->loadAllFromArray($data);
+  protected function loadPage() {
+    return $this->loadStandardPage($this->newResultObject());
   }
 
   protected function willFilterPage(array $commits) {
@@ -296,8 +266,8 @@
     return $commits;
   }
 
-  protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
-    $where = array();
+  protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+    $where = parent::buildWhereClauseParts($conn);
 
     if ($this->repositoryPHIDs !== null) {
       $map_repositories = id(new PhabricatorRepositoryQuery())
@@ -317,42 +287,42 @@
 
     if ($this->ids !== null) {
       $where[] = qsprintf(
-        $conn_r,
+        $conn,
         'commit.id IN (%Ld)',
         $this->ids);
     }
 
     if ($this->phids !== null) {
       $where[] = qsprintf(
-        $conn_r,
+        $conn,
         'commit.phid IN (%Ls)',
         $this->phids);
     }
 
     if ($this->repositoryIDs !== null) {
       $where[] = qsprintf(
-        $conn_r,
+        $conn,
         'commit.repositoryID IN (%Ld)',
         $this->repositoryIDs);
     }
 
     if ($this->authorPHIDs !== null) {
       $where[] = qsprintf(
-        $conn_r,
+        $conn,
         'commit.authorPHID IN (%Ls)',
         $this->authorPHIDs);
     }
 
     if ($this->epochMin !== null) {
       $where[] = qsprintf(
-        $conn_r,
+        $conn,
         'commit.epoch >= %d',
         $this->epochMin);
     }
 
     if ($this->epochMax !== null) {
       $where[] = qsprintf(
-        $conn_r,
+        $conn,
         'commit.epoch <= %d',
         $this->epochMax);
     }
@@ -360,13 +330,13 @@
     if ($this->importing !== null) {
       if ($this->importing) {
         $where[] = qsprintf(
-          $conn_r,
+          $conn,
           '(commit.importStatus & %d) != %d',
           PhabricatorRepositoryCommit::IMPORTED_ALL,
           PhabricatorRepositoryCommit::IMPORTED_ALL);
       } else {
         $where[] = qsprintf(
-          $conn_r,
+          $conn,
           '(commit.importStatus & %d) = %d',
           PhabricatorRepositoryCommit::IMPORTED_ALL,
           PhabricatorRepositoryCommit::IMPORTED_ALL);
@@ -409,7 +379,7 @@
 
       foreach ($bare as $identifier) {
         $sql[] = qsprintf(
-          $conn_r,
+          $conn,
           '(commit.commitIdentifier LIKE %> AND '.
           'LENGTH(commit.commitIdentifier) = 40)',
           $identifier);
@@ -437,7 +407,7 @@
               continue;
             }
             $sql[] = qsprintf(
-              $conn_r,
+              $conn,
               '(commit.repositoryID = %d AND commit.commitIdentifier = %s)',
               $repo->getID(),
               // NOTE: Because the 'commitIdentifier' column is a string, MySQL
@@ -449,7 +419,7 @@
               continue;
             }
             $sql[] = qsprintf(
-              $conn_r,
+              $conn,
               '(commit.repositoryID = %d AND commit.commitIdentifier LIKE %>)',
               $repo->getID(),
               $ref['identifier']);
@@ -470,28 +440,23 @@
 
     if ($this->auditIDs !== null) {
       $where[] = qsprintf(
-        $conn_r,
+        $conn,
         'audit.id IN (%Ld)',
         $this->auditIDs);
     }
 
     if ($this->auditorPHIDs !== null) {
       $where[] = qsprintf(
-        $conn_r,
+        $conn,
         'audit.auditorPHID IN (%Ls)',
         $this->auditorPHIDs);
     }
 
-    if ($this->auditAwaitingUser) {
-      $awaiting_user_phid = $this->auditAwaitingUser->getPHID();
-      // Exclude package and project audits associated with commits where
-      // the user is the author.
+    if ($this->needsAuditByPHIDs !== null) {
       $where[] = qsprintf(
-        $conn_r,
-        '(commit.authorPHID IS NULL OR commit.authorPHID != %s)
-          OR (audit.auditorPHID = %s)',
-        $awaiting_user_phid,
-        $awaiting_user_phid);
+        $conn,
+        'needs.auditorPHID IN (%Ls)',
+        $this->needsAuditByPHIDs);
     }
 
     $status = $this->auditStatus;
@@ -499,33 +464,27 @@
       switch ($status) {
         case self::AUDIT_STATUS_PARTIAL:
           $where[] = qsprintf(
-            $conn_r,
+            $conn,
             'commit.auditStatus = %d',
             PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED);
           break;
         case self::AUDIT_STATUS_ACCEPTED:
           $where[] = qsprintf(
-            $conn_r,
+            $conn,
             'commit.auditStatus = %d',
             PhabricatorAuditCommitStatusConstants::FULLY_AUDITED);
           break;
         case self::AUDIT_STATUS_CONCERN:
           $where[] = qsprintf(
-            $conn_r,
-            'audit.auditStatus = %s',
+            $conn,
+            'status.auditStatus = %s',
             PhabricatorAuditStatusConstants::CONCERNED);
           break;
         case self::AUDIT_STATUS_OPEN:
           $where[] = qsprintf(
-            $conn_r,
-            'audit.auditStatus in (%Ls)',
+            $conn,
+            'status.auditStatus in (%Ls)',
             PhabricatorAuditStatusConstants::getOpenStatusConstants());
-          if ($this->auditAwaitingUser) {
-            $where[] = qsprintf(
-              $conn_r,
-              'awaiting.auditStatus IS NULL OR awaiting.auditStatus != %s',
-              PhabricatorAuditStatusConstants::RESIGNED);
-          }
           break;
         case self::AUDIT_STATUS_ANY:
           break;
@@ -545,9 +504,7 @@
       }
     }
 
-    $where[] = $this->buildPagingClause($conn_r);
-
-    return $this->formatWhereClause($where);
+    return $where;
   }
 
   protected function didFilterResults(array $filtered) {
@@ -560,56 +517,113 @@
     }
   }
 
-  protected function buildJoinClause(AphrontDatabaseConnection $conn_r) {
-    $joins = array();
+  private function shouldJoinStatus() {
+    return $this->auditStatus;
+  }
+
+  private function shouldJoinAudits() {
+    return $this->auditIDs || $this->auditorPHIDs;
+  }
+
+  private function shouldJoinNeeds() {
+    return $this->needsAuditByPHIDs;
+  }
+
+  protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
+    $join = parent::buildJoinClauseParts($conn);
     $audit_request = new PhabricatorRepositoryAuditRequest();
 
+    if ($this->shouldJoinStatus()) {
+      $join[] = qsprintf(
+        $conn,
+        'LEFT JOIN %T status ON commit.phid = status.commitPHID',
+        $audit_request->getTableName());
+    }
+
     if ($this->shouldJoinAudits()) {
-      $joins[] = qsprintf(
-        $conn_r,
-        '%Q %T audit ON commit.phid = audit.commitPHID',
-        ($this->rowsMustHaveAudits() ? 'JOIN' : 'LEFT JOIN'),
+      $join[] = qsprintf(
+        $conn,
+        'JOIN %T audit ON commit.phid = audit.commitPHID',
         $audit_request->getTableName());
     }
 
-    if ($this->auditAwaitingUser) {
-      // Join the request table on the awaiting user's requests, so we can
-      // filter out package and project requests which the user has resigned
-      // from.
-      $joins[] = qsprintf(
-        $conn_r,
-        'LEFT JOIN %T awaiting ON audit.commitPHID = awaiting.commitPHID AND
-        awaiting.auditorPHID = %s',
+    if ($this->shouldJoinNeeds()) {
+      $join[] = qsprintf(
+        $conn,
+        'JOIN %T needs ON commit.phid = needs.commitPHID
+          AND needs.auditStatus IN (%Ls)',
         $audit_request->getTableName(),
-        $this->auditAwaitingUser->getPHID());
+        array(
+          PhabricatorAuditStatusConstants::AUDIT_REQUESTED,
+          PhabricatorAuditStatusConstants::AUDIT_REQUIRED,
+        ));
     }
 
-    if ($joins) {
-      return implode(' ', $joins);
-    } else {
-      return '';
-    }
+    return $join;
   }
 
-  protected function buildGroupClause(AphrontDatabaseConnection $conn_r) {
-    $should_group = $this->shouldJoinAudits();
+  protected function shouldGroupQueryResultRows() {
+    if ($this->shouldJoinStatus()) {
+      return true;
+    }
 
-    // TODO: Currently, the audit table is missing a unique key, so we may
-    // require a GROUP BY if we perform this join. See T1768. This can be
-    // removed once the table has the key.
-    if ($this->auditAwaitingUser) {
-      $should_group = true;
+    if ($this->shouldJoinAudits()) {
+      return true;
     }
 
-    if ($should_group) {
-      return 'GROUP BY commit.id';
-    } else {
-      return '';
+    if ($this->shouldJoinNeeds()) {
+      return true;
     }
+
+    return parent::shouldGroupQueryResultRows();
   }
 
   public function getQueryApplicationClass() {
     return 'PhabricatorDiffusionApplication';
   }
 
+  public function getOrderableColumns() {
+    return parent::getOrderableColumns() + array(
+      'epoch' => array(
+        'table' => $this->getPrimaryTableAlias(),
+        'column' => 'epoch',
+        'type' => 'int',
+        'reverse' => false,
+      ),
+    );
+  }
+
+  protected function getPagingValueMap($cursor, array $keys) {
+    $commit = $this->loadCursorObject($cursor);
+    return array(
+      'id' => $commit->getID(),
+      'epoch' => $commit->getEpoch(),
+    );
+  }
+
+  public function getBuiltinOrders() {
+    $parent = parent::getBuiltinOrders();
+
+    // Rename the default ID-based orders.
+    $parent['importnew'] = array(
+      'name' => pht('Import Date (Newest First)'),
+    ) + $parent['newest'];
+
+    $parent['importold'] = array(
+      'name' => pht('Import Date (Oldest First)'),
+    ) + $parent['oldest'];
+
+    return array(
+      'newest' => array(
+        'vector' => array('epoch', 'id'),
+        'name' => pht('Commit Date (Newest First)'),
+      ),
+      'oldest' => array(
+        'vector' => array('-epoch', '-id'),
+        'name' => pht('Commit Date (Oldest First)'),
+      ),
+    ) + $parent;
+  }
+
+
 }
diff --git a/src/applications/diffusion/typeahead/DiffusionAuditorFunctionDatasource.php b/src/applications/diffusion/typeahead/DiffusionAuditorFunctionDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/typeahead/DiffusionAuditorFunctionDatasource.php
@@ -0,0 +1,25 @@
+<?php
+
+final class DiffusionAuditorFunctionDatasource
+  extends PhabricatorTypeaheadCompositeDatasource {
+
+  public function getBrowseTitle() {
+    return pht('Browse Auditors');
+  }
+
+  public function getPlaceholderText() {
+    return pht('Type a user, project, package name or function...');
+  }
+
+  public function getDatasourceApplicationClass() {
+    return 'PhabricatorDiffusionApplication';
+  }
+
+  public function getComponentDatasources() {
+    return array(
+      new PhabricatorProjectOrUserFunctionDatasource(),
+      new PhabricatorOwnersPackageFunctionDatasource(),
+    );
+  }
+
+}
diff --git a/src/applications/home/controller/PhabricatorHomeMainController.php b/src/applications/home/controller/PhabricatorHomeMainController.php
--- a/src/applications/home/controller/PhabricatorHomeMainController.php
+++ b/src/applications/home/controller/PhabricatorHomeMainController.php
@@ -349,9 +349,8 @@
 
     $query = id(new DiffusionCommitQuery())
       ->setViewer($user)
-      ->withAuditorPHIDs($phids)
+      ->withNeedsAuditByPHIDs($phids)
       ->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_OPEN)
-      ->withAuditAwaitingUser($user)
       ->needAuditRequests(true)
       ->needCommitData(true)
       ->setLimit(10);
diff --git a/src/applications/owners/typeahead/PhabricatorOwnersPackageFunctionDatasource.php b/src/applications/owners/typeahead/PhabricatorOwnersPackageFunctionDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/owners/typeahead/PhabricatorOwnersPackageFunctionDatasource.php
@@ -0,0 +1,25 @@
+<?php
+
+final class PhabricatorOwnersPackageFunctionDatasource
+  extends PhabricatorTypeaheadCompositeDatasource {
+
+  public function getBrowseTitle() {
+    return pht('Browse Packages');
+  }
+
+  public function getPlaceholderText() {
+    return pht('Type a package name or function...');
+  }
+
+  public function getDatasourceApplicationClass() {
+    return 'PhabricatorOwnersApplication';
+  }
+
+  public function getComponentDatasources() {
+    return array(
+      new PhabricatorOwnersPackageDatasource(),
+      new PhabricatorOwnersPackageOwnerDatasource(),
+    );
+  }
+
+}
diff --git a/src/applications/owners/typeahead/PhabricatorOwnersPackageOwnerDatasource.php b/src/applications/owners/typeahead/PhabricatorOwnersPackageOwnerDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/owners/typeahead/PhabricatorOwnersPackageOwnerDatasource.php
@@ -0,0 +1,140 @@
+<?php
+
+final class PhabricatorOwnersPackageOwnerDatasource
+  extends PhabricatorTypeaheadCompositeDatasource {
+
+  public function getBrowseTitle() {
+    return pht('Browse Packages by Owner');
+  }
+
+  public function getPlaceholderText() {
+    return pht('Type packages(<user>) or packages(<project>)...');
+  }
+
+  public function getDatasourceApplicationClass() {
+    return 'PhabricatorOwnersApplication';
+  }
+
+  public function getComponentDatasources() {
+    return array(
+      new PhabricatorPeopleDatasource(),
+      new PhabricatorProjectDatasource(),
+    );
+  }
+
+  public function getDatasourceFunctions() {
+    return array(
+      'packages' => array(
+        'name' => pht('Packages: ...'),
+        'arguments' => pht('owner'),
+        'summary' => pht("Find results in any of an owner's projects."),
+        'description' => pht(
+          "This function allows you to find results associated with any ".
+          "of the packages a specified user or project is an owner of. ".
+          "For example, this will find results associated with all of ".
+          "the projects `%s` owns:\n\n%s\n\n",
+          'alincoln',
+          '> packages(alincoln)'),
+      ),
+    );
+  }
+
+  protected function didLoadResults(array $results) {
+    foreach ($results as $result) {
+      $result
+        ->setColor(null)
+        ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
+        ->setIcon('fa-asterisk')
+        ->setPHID('packages('.$result->getPHID().')')
+        ->setDisplayName(pht('Packages: %s', $result->getDisplayName()))
+        ->setName($result->getName().' packages');
+    }
+
+    return $results;
+  }
+
+  protected function evaluateFunction($function, array $argv_list) {
+    $phids = array();
+    foreach ($argv_list as $argv) {
+      $phids[] = head($argv);
+    }
+
+    $phids = $this->resolvePHIDs($phids);
+
+    $user_phids = array();
+    foreach ($phids as $phid) {
+      if (phid_get_type($phid) == PhabricatorPeopleUserPHIDType::TYPECONST) {
+        $user_phids[] = $phid;
+      }
+    }
+
+    if ($user_phids) {
+      $projects = id(new PhabricatorProjectQuery())
+        ->setViewer($this->getViewer())
+        ->withMemberPHIDs($user_phids)
+        ->execute();
+      foreach ($projects as $project) {
+        $phids[] = $project->getPHID();
+      }
+    }
+
+    return $phids;
+  }
+
+  public function renderFunctionTokens($function, array $argv_list) {
+    $phids = array();
+    foreach ($argv_list as $argv) {
+      $phids[] = head($argv);
+    }
+
+    $phids = $this->resolvePHIDs($phids);
+
+    $tokens = $this->renderTokens($phids);
+    foreach ($tokens as $token) {
+      $token->setColor(null);
+      if ($token->isInvalid()) {
+        $token
+          ->setValue(pht('Packages: Invalid Owner'));
+      } else {
+        $token
+          ->setIcon('fa-asterisk')
+          ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
+          ->setKey('packages('.$token->getKey().')')
+          ->setValue(pht('Packages: %s', $token->getValue()));
+      }
+    }
+
+    return $tokens;
+  }
+
+  private function resolvePHIDs(array $phids) {
+
+    // TODO: It would be nice for this to handle `packages(#project)` from a
+    // query string or eventually via Conduit. This could also share code with
+    // PhabricatorProjectLogicalUserDatasource.
+
+    $usernames = array();
+    foreach ($phids as $key => $phid) {
+      if (phid_get_type($phid) != PhabricatorPeopleUserPHIDType::TYPECONST) {
+        $usernames[$key] = $phid;
+      }
+    }
+
+    if ($usernames) {
+      $users = id(new PhabricatorPeopleQuery())
+        ->setViewer($this->getViewer())
+        ->withUsernames($usernames)
+        ->execute();
+      $users = mpull($users, null, 'getUsername');
+      foreach ($usernames as $key => $username) {
+        $user = idx($users, $username);
+        if ($user) {
+          $phids[$key] = $user->getPHID();
+        }
+      }
+    }
+
+    return $phids;
+  }
+
+}
diff --git a/src/applications/project/typeahead/PhabricatorProjectOrUserFunctionDatasource.php b/src/applications/project/typeahead/PhabricatorProjectOrUserFunctionDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/typeahead/PhabricatorProjectOrUserFunctionDatasource.php
@@ -0,0 +1,25 @@
+<?php
+
+final class PhabricatorProjectOrUserFunctionDatasource
+  extends PhabricatorTypeaheadCompositeDatasource {
+
+  public function getBrowseTitle() {
+    return pht('Browse Users and Projects');
+  }
+
+  public function getPlaceholderText() {
+    return pht('Type a user, project name, or function...');
+  }
+
+  public function getComponentDatasources() {
+    return array(
+      new PhabricatorViewerDatasource(),
+      new PhabricatorPeopleDatasource(),
+      new PhabricatorProjectDatasource(),
+      new PhabricatorProjectMembersDatasource(),
+      new PhabricatorProjectUserFunctionDatasource(),
+    );
+  }
+
+
+}
diff --git a/src/applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php b/src/applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php
@@ -0,0 +1,36 @@
+<?php
+
+final class PhabricatorProjectUserFunctionDatasource
+  extends PhabricatorTypeaheadCompositeDatasource {
+
+  public function getBrowseTitle() {
+    return pht('Browse User Projects');
+  }
+
+  public function getPlaceholderText() {
+    return pht('Type projects(<user>)...');
+  }
+
+  public function getDatasourceApplicationClass() {
+    return 'PhabricatorProjectApplication';
+  }
+
+  public function getComponentDatasources() {
+    return array(
+      new PhabricatorProjectLogicalUserDatasource(),
+    );
+  }
+
+  protected function evaluateFunction($function, array $argv_list) {
+    $result = parent::evaluateFunction($function, $argv_list);
+
+    foreach ($result as $k => $v) {
+      if ($v instanceof PhabricatorQueryConstraint) {
+        $result[$k] = $v->getValue();
+      }
+    }
+
+    return $result;
+  }
+
+}
diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php
--- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php
@@ -98,6 +98,12 @@
           'columns' => array('commitIdentifier', 'repositoryID'),
           'unique' => true,
         ),
+        'key_epoch' => array(
+          'columns' => array('epoch'),
+        ),
+        'key_author' => array(
+          'columns' => array('authorPHID', 'epoch'),
+        ),
       ),
       self::CONFIG_NO_MUTATE => array(
         'importStatus',