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
@@ -550,6 +550,7 @@
     'DifferentialRevisionHasTaskRelationship' => 'applications/differential/relationships/DifferentialRevisionHasTaskRelationship.php',
     'DifferentialRevisionHeraldField' => 'applications/differential/herald/DifferentialRevisionHeraldField.php',
     'DifferentialRevisionHeraldFieldGroup' => 'applications/differential/herald/DifferentialRevisionHeraldFieldGroup.php',
+    'DifferentialRevisionHoldDraftTransaction' => 'applications/differential/xaction/DifferentialRevisionHoldDraftTransaction.php',
     'DifferentialRevisionIDCommitMessageField' => 'applications/differential/field/DifferentialRevisionIDCommitMessageField.php',
     'DifferentialRevisionInlineTransaction' => 'applications/differential/xaction/DifferentialRevisionInlineTransaction.php',
     'DifferentialRevisionInlinesController' => 'applications/differential/controller/DifferentialRevisionInlinesController.php',
@@ -5592,6 +5593,7 @@
     'DifferentialRevisionHasTaskRelationship' => 'DifferentialRevisionRelationship',
     'DifferentialRevisionHeraldField' => 'HeraldField',
     'DifferentialRevisionHeraldFieldGroup' => 'HeraldFieldGroup',
+    'DifferentialRevisionHoldDraftTransaction' => 'DifferentialRevisionTransactionType',
     'DifferentialRevisionIDCommitMessageField' => 'DifferentialCommitMessageField',
     'DifferentialRevisionInlineTransaction' => 'PhabricatorModularTransactionType',
     'DifferentialRevisionInlinesController' => 'DifferentialController',
diff --git a/src/applications/differential/customfield/DifferentialDraftField.php b/src/applications/differential/customfield/DifferentialDraftField.php
--- a/src/applications/differential/customfield/DifferentialDraftField.php
+++ b/src/applications/differential/customfield/DifferentialDraftField.php
@@ -36,6 +36,12 @@
       return array();
     }
 
+    // If the author has held this revision as a draft explicitly, don't
+    // show any misleading messages about it autosubmitting later.
+    if ($revision->getHoldAsDraft()) {
+      return array();
+    }
+
     $warnings = array();
 
     $blocking_map = array(
diff --git a/src/applications/differential/editor/DifferentialRevisionEditEngine.php b/src/applications/differential/editor/DifferentialRevisionEditEngine.php
--- a/src/applications/differential/editor/DifferentialRevisionEditEngine.php
+++ b/src/applications/differential/editor/DifferentialRevisionEditEngine.php
@@ -235,6 +235,22 @@
       $fields[] = $action->newEditField($object, $viewer);
     }
 
+    $fields[] = id(new PhabricatorBoolEditField())
+      ->setKey('draft')
+      ->setLabel(pht('Hold as Draft'))
+      ->setIsConduitOnly(true)
+      ->setOptions(
+        pht('Autosubmit Once Builds Finish'),
+        pht('Hold as Draft'))
+      ->setTransactionType(
+        DifferentialRevisionHoldDraftTransaction::TRANSACTIONTYPE)
+      ->setDescription(pht('Hold revision as as draft.'))
+      ->setConduitDescription(
+        pht(
+          'Change autosubmission from draft state after builds finish.'))
+      ->setConduitTypeDescription(pht('New "Hold as Draft" setting.'))
+      ->setValue($object->getHoldAsDraft());
+
     return $fields;
   }
 
diff --git a/src/applications/differential/editor/DifferentialTransactionEditor.php b/src/applications/differential/editor/DifferentialTransactionEditor.php
--- a/src/applications/differential/editor/DifferentialTransactionEditor.php
+++ b/src/applications/differential/editor/DifferentialTransactionEditor.php
@@ -1540,7 +1540,7 @@
   protected function didApplyTransactions($object, array $xactions) {
     // If a draft revision has no outstanding builds and we're automatically
     // making drafts public after builds finish, make the revision public.
-    $auto_undraft = true;
+    $auto_undraft = !$object->getHoldAsDraft();
 
     if ($object->isDraft() && $auto_undraft) {
       $active_builds = $this->hasActiveBuilds($object);
diff --git a/src/applications/differential/storage/DifferentialRevision.php b/src/applications/differential/storage/DifferentialRevision.php
--- a/src/applications/differential/storage/DifferentialRevision.php
+++ b/src/applications/differential/storage/DifferentialRevision.php
@@ -57,6 +57,7 @@
   const RELATION_SUBSCRIBED   = 'subd';
 
   const PROPERTY_CLOSED_FROM_ACCEPTED = 'wasAcceptedBeforeClose';
+  const PROPERTY_DRAFT_HOLD = 'draft.hold';
 
   public static function initializeNewRevision(PhabricatorUser $actor) {
     $app = id(new PhabricatorApplicationQuery())
@@ -708,6 +709,14 @@
     return false;
   }
 
+  public function getHoldAsDraft() {
+    return $this->getProperty(self::PROPERTY_DRAFT_HOLD, false);
+  }
+
+  public function setHoldAsDraft($hold) {
+    return $this->setProperty(self::PROPERTY_DRAFT_HOLD, $hold);
+  }
+
   public function loadActiveBuilds(PhabricatorUser $viewer) {
     $diff = $this->getActiveDiff();
 
diff --git a/src/applications/differential/xaction/DifferentialRevisionHoldDraftTransaction.php b/src/applications/differential/xaction/DifferentialRevisionHoldDraftTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/xaction/DifferentialRevisionHoldDraftTransaction.php
@@ -0,0 +1,47 @@
+<?php
+
+final class DifferentialRevisionHoldDraftTransaction
+  extends DifferentialRevisionTransactionType {
+
+  const TRANSACTIONTYPE = 'draft';
+  const EDITKEY = 'draft';
+
+  public function generateOldValue($object) {
+    return (bool)$object->getHoldAsDraft();
+  }
+
+  public function generateNewValue($object, $value) {
+    return (bool)$value;
+  }
+
+  public function applyInternalEffects($object, $value) {
+    $object->setHoldAsDraft($value);
+  }
+
+  public function getTitle() {
+    if ($this->getNewValue()) {
+      return pht(
+        '%s held this revision as a draft.',
+        $this->renderAuthor());
+    } else {
+      return pht(
+        '%s set this revision to automatically submit once builds complete.',
+        $this->renderAuthor());
+    }
+  }
+
+  public function getTitleForFeed() {
+    if ($this->getNewValue()) {
+      return pht(
+        '%s held %s as a draft.',
+        $this->renderAuthor(),
+        $this->renderObject());
+    } else {
+      return pht(
+        '%s set %s to automatically submit once builds complete.',
+        $this->renderAuthor(),
+        $this->renderObject());
+    }
+  }
+
+}