diff --git a/src/infrastructure/customfield/field/PhabricatorCustomFieldList.php b/src/infrastructure/customfield/field/PhabricatorCustomFieldList.php
index bb1c445be..bb030154d 100644
--- a/src/infrastructure/customfield/field/PhabricatorCustomFieldList.php
+++ b/src/infrastructure/customfield/field/PhabricatorCustomFieldList.php
@@ -1,260 +1,263 @@
 <?php
 
 /**
  * Convenience class to perform operations on an entire field list, like reading
  * all values from storage.
  *
  *   $field_list = new PhabricatorCustomFieldList($fields);
  *
  */
 final class PhabricatorCustomFieldList extends Phobject {
 
   private $fields;
 
   public function __construct(array $fields) {
     assert_instances_of($fields, 'PhabricatorCustomField');
     $this->fields = $fields;
   }
 
   public function getFields() {
     return $this->fields;
   }
 
   public function setViewer(PhabricatorUser $viewer) {
     foreach ($this->getFields() as $field) {
       $field->setViewer($viewer);
     }
     return $this;
   }
 
+
   /**
    * Read stored values for all fields which support storage.
    *
    * @param PhabricatorCustomFieldInterface Object to read field values for.
    * @return void
    */
   public function readFieldsFromStorage(
     PhabricatorCustomFieldInterface $object) {
 
     $keys = array();
     foreach ($this->fields as $field) {
       if ($field->shouldEnableForRole(PhabricatorCustomField::ROLE_STORAGE)) {
         $keys[$field->getFieldIndex()] = $field;
       }
     }
 
     if (!$keys) {
       return;
     }
 
     // NOTE: We assume all fields share the same storage. This isn't guaranteed
     // to be true, but always is for now.
 
     $table = head($keys)->newStorageObject();
 
     $objects = array();
     if ($object->getPHID()) {
       $objects = $table->loadAllWhere(
         'objectPHID = %s AND fieldIndex IN (%Ls)',
         $object->getPHID(),
         array_keys($keys));
       $objects = mpull($objects, null, 'getFieldIndex');
     }
 
     foreach ($keys as $key => $field) {
       $storage = idx($objects, $key);
       if ($storage) {
         $field->setValueFromStorage($storage->getFieldValue());
-      } else {
+      } else if ($object->getPHID()) {
+        // NOTE: We set this only if the object exists. Otherwise, we allow the
+        // field to retain any default value it may have.
         $field->setValueFromStorage(null);
       }
     }
   }
 
   public function appendFieldsToForm(AphrontFormView $form) {
     foreach ($this->fields as $field) {
       if ($field->shouldEnableForRole(PhabricatorCustomField::ROLE_EDIT)) {
         $form->appendChild($field->renderEditControl());
       }
     }
   }
 
   public function appendFieldsToPropertyList(
     PhabricatorCustomFieldInterface $object,
     PhabricatorUser $viewer,
     PhabricatorPropertyListView $view) {
 
     $this->readFieldsFromStorage($object);
     $fields = $this->fields;
 
     foreach ($fields as $field) {
       $field->setViewer($viewer);
     }
 
     // Move all the blocks to the end, regardless of their configuration order,
     // because it always looks silly to render a block in the middle of a list
     // of properties.
     $head = array();
     $tail = array();
     foreach ($fields as $key => $field) {
       $style = $field->getStyleForPropertyView();
       switch ($style) {
         case 'property':
         case 'header':
           $head[$key] = $field;
           break;
         case 'block':
           $tail[$key] = $field;
           break;
         default:
           throw new Exception(
             "Unknown field property view style '{$style}'; valid styles are ".
             "'block' and 'property'.");
       }
     }
     $fields = $head + $tail;
 
     $add_header = null;
 
     foreach ($fields as $field) {
       $label = $field->renderPropertyViewLabel();
       $value = $field->renderPropertyViewValue();
       if ($value !== null) {
         switch ($field->getStyleForPropertyView()) {
           case 'header':
             // We want to hide headers if the fields the're assciated with
             // don't actually produce any visible properties. For example, in a
             // list like this:
             //
             //   Header A
             //   Prop A: Value A
             //   Header B
             //   Prop B: Value B
             //
             // ...if the "Prop A" field returns `null` when rendering its
             // property value and we rendered naively, we'd get this:
             //
             //   Header A
             //   Header B
             //   Prop B: Value B
             //
             // This is silly. Instead, we hide "Header A".
             $add_header = $value;
             break;
           case 'property':
             if ($add_header !== null) {
               // Add the most recently seen header.
               $view->addSectionHeader($add_header);
               $add_header = null;
             }
             $view->addProperty($label, $value);
             break;
           case 'block':
             $view->invokeWillRenderEvent();
             if ($label !== null) {
               $view->addSectionHeader($label);
             }
             $view->addTextContent($value);
             break;
         }
       }
     }
   }
 
   public function buildFieldTransactionsFromRequest(
     PhabricatorApplicationTransaction $template,
     AphrontRequest $request) {
 
     $xactions = array();
 
     $role = PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS;
     foreach ($this->fields as $field) {
       if (!$field->shouldEnableForRole($role)) {
         continue;
       }
 
       $old_value = $field->getOldValueForApplicationTransactions();
 
       $field->readValueFromRequest($request);
 
       $xaction = id(clone $template)
         ->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
         ->setMetadataValue('customfield:key', $field->getFieldKey())
         ->setOldValue($old_value)
         ->setNewValue($field->getNewValueForApplicationTransactions());
 
       $xactions[] = $xaction;
     }
 
     return $xactions;
   }
 
 
   /**
    * Publish field indexes into index tables, so ApplicationSearch can search
    * them.
    *
    * @return void
    */
   public function rebuildIndexes(PhabricatorCustomFieldInterface $object) {
     $indexes = array();
     $index_keys = array();
 
     $phid = $object->getPHID();
 
     $role = PhabricatorCustomField::ROLE_APPLICATIONSEARCH;
     foreach ($this->fields as $field) {
       if (!$field->shouldEnableForRole($role)) {
         continue;
       }
 
       $index_keys[$field->getFieldIndex()] = true;
 
       foreach ($field->buildFieldIndexes() as $index) {
         $index->setObjectPHID($phid);
         $indexes[$index->getTableName()][] = $index;
       }
     }
 
     if (!$indexes) {
       return;
     }
 
     $any_index = head(head($indexes));
     $conn_w = $any_index->establishConnection('w');
 
     foreach ($indexes as $table => $index_list) {
       $sql = array();
       foreach ($index_list as $index) {
         $sql[] = $index->formatForInsert($conn_w);
       }
       $indexes[$table] = $sql;
     }
 
     $any_index->openTransaction();
 
       foreach ($indexes as $table => $sql_list) {
         queryfx(
           $conn_w,
           'DELETE FROM %T WHERE objectPHID = %s AND indexKey IN (%Ls)',
           $table,
           $phid,
           array_keys($index_keys));
 
         if (!$sql_list) {
           continue;
         }
 
         foreach (PhabricatorLiskDAO::chunkSQL($sql_list) as $chunk) {
           queryfx(
             $conn_w,
             'INSERT INTO %T (objectPHID, indexKey, indexValue) VALUES %Q',
             $table,
             $chunk);
         }
       }
 
     $any_index->saveTransaction();
   }
 
 }
diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
index 7d7323465..2f79bfd22 100644
--- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
+++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
@@ -1,300 +1,303 @@
 <?php
 
 abstract class PhabricatorStandardCustomField
   extends PhabricatorCustomField {
 
   private $fieldKey;
   private $fieldName;
   private $fieldValue;
   private $fieldDescription;
   private $fieldConfig;
   private $applicationField;
   private $strings;
   private $caption;
   private $fieldError;
   private $required;
   private $default;
 
   abstract public function getFieldType();
 
   public static function buildStandardFields(
     PhabricatorCustomField $template,
     array $config) {
 
     $types = id(new PhutilSymbolLoader())
       ->setAncestorClass(__CLASS__)
       ->loadObjects();
     $types = mpull($types, null, 'getFieldType');
 
     $fields = array();
     foreach ($config as $key => $value) {
       $type = idx($value, 'type', 'text');
       if (empty($types[$type])) {
         // TODO: We should have better typechecking somewhere, and then make
         // this more serious.
         continue;
       }
 
       $namespace = $template->getStandardCustomFieldNamespace();
       $full_key = "std:{$namespace}:{$key}";
 
       $template = clone $template;
       $standard = id(clone $types[$type])
         ->setFieldKey($full_key)
         ->setFieldConfig($value)
         ->setApplicationField($template);
 
       $field = $template->setProxy($standard);
       $fields[] = $field;
     }
 
     return $fields;
   }
 
   public function setApplicationField(
     PhabricatorStandardCustomFieldInterface $application_field) {
     $this->applicationField = $application_field;
     return $this;
   }
 
   public function getApplicationField() {
     return $this->applicationField;
   }
 
   public function setFieldName($name) {
     $this->fieldName = $name;
     return $this;
   }
 
   public function getFieldValue() {
     return $this->fieldValue;
   }
 
   public function setFieldValue($value) {
     $this->fieldValue = $value;
     return $this;
   }
 
   public function setCaption($caption) {
     $this->caption = $caption;
     return $this;
   }
 
   public function getCaption() {
     return $this->caption;
   }
 
   public function setFieldDescription($description) {
     $this->fieldDescription = $description;
     return $this;
   }
 
   public function setFieldConfig(array $config) {
     foreach ($config as $key => $value) {
       switch ($key) {
         case 'name':
           $this->setFieldName($value);
           break;
         case 'description':
           $this->setFieldDescription($value);
           break;
         case 'strings':
           $this->setStrings($value);
           break;
         case 'caption':
           $this->setCaption($value);
           break;
         case 'required':
           $this->setRequired($value);
           $this->setFieldError(true);
           break;
+        case 'default':
+          $this->setFieldValue($value);
+          break;
         case 'type':
           // We set this earlier on.
           break;
       }
     }
     $this->fieldConfig = $config;
     return $this;
   }
 
   public function getFieldConfigValue($key, $default = null) {
     return idx($this->fieldConfig, $key, $default);
   }
 
   public function setFieldError($field_error) {
     $this->fieldError = $field_error;
     return $this;
   }
 
   public function getFieldError() {
     return $this->fieldError;
   }
 
   public function setRequired($required) {
     $this->required = $required;
     return $this;
   }
 
   public function getRequired() {
     return $this->required;
   }
 
 
 /* -(  PhabricatorCustomField  )--------------------------------------------- */
 
 
   public function setFieldKey($field_key) {
     $this->fieldKey = $field_key;
     return $this;
   }
 
   public function getFieldKey() {
     return $this->fieldKey;
   }
 
   public function getFieldName() {
     return coalesce($this->fieldName, parent::getFieldName());
   }
 
   public function getFieldDescription() {
     return coalesce($this->fieldDescription, parent::getFieldDescription());
   }
 
   public function setStrings(array $strings) {
     $this->strings = $strings;
     return;
   }
 
   public function getString($key, $default = null) {
     return idx($this->strings, $key, $default);
   }
 
   public function shouldUseStorage() {
     return true;
   }
 
   public function getValueForStorage() {
     return $this->getFieldValue();
   }
 
   public function setValueFromStorage($value) {
     return $this->setFieldValue($value);
   }
 
   public function shouldAppearInApplicationTransactions() {
     return true;
   }
 
   public function shouldAppearInEditView() {
     return $this->getFieldConfigValue('edit', true);
   }
 
   public function readValueFromRequest(AphrontRequest $request) {
     $value = $request->getStr($this->getFieldKey());
     if (!strlen($value)) {
       $value = null;
     }
     $this->setFieldValue($value);
   }
 
   public function renderEditControl() {
     return id(new AphrontFormTextControl())
       ->setName($this->getFieldKey())
       ->setCaption($this->getCaption())
       ->setValue($this->getFieldValue())
       ->setError($this->getFieldError())
       ->setLabel($this->getFieldName());
   }
 
   public function newStorageObject() {
     return $this->getApplicationField()->newStorageObject();
   }
 
   public function shouldAppearInPropertyView() {
     return $this->getFieldConfigValue('view', true);
   }
 
   public function renderPropertyViewValue() {
     return $this->getFieldValue();
   }
 
   public function shouldAppearInApplicationSearch() {
     return $this->getFieldConfigValue('search', false);
   }
 
   protected function newStringIndexStorage() {
     return $this->getApplicationField()->newStringIndexStorage();
   }
 
   protected function newNumericIndexStorage() {
     return $this->getApplicationField()->newNumericIndexStorage();
   }
 
   public function buildFieldIndexes() {
     return array();
   }
 
   public function readApplicationSearchValueFromRequest(
     PhabricatorApplicationSearchEngine $engine,
     AphrontRequest $request) {
     return;
   }
 
   public function applyApplicationSearchConstraintToQuery(
     PhabricatorApplicationSearchEngine $engine,
     PhabricatorCursorPagedPolicyAwareQuery $query,
     $value) {
     return;
   }
 
   public function appendToApplicationSearchForm(
     PhabricatorApplicationSearchEngine $engine,
     AphrontFormView $form,
     $value,
     array $handles) {
     return;
   }
 
   public function validateApplicationTransactions(
     PhabricatorApplicationTransactionEditor $editor,
     $type,
     array $xactions) {
 
     $this->setFieldError(null);
 
     $errors = parent::validateApplicationTransactions(
       $editor,
       $type,
       $xactions);
 
     if ($this->getRequired()) {
       $value = null;
       $transaction = null;
       foreach ($xactions as $xaction) {
         $value = $xaction->getNewValue();
         if (!$this->isValueEmpty($value)) {
           $transaction = $xaction;
           break;
         }
       }
       if ($this->isValueEmpty($value)) {
         $errors[] = new PhabricatorApplicationTransactionValidationError(
           $type,
           pht('Required'),
           pht('%s is required.', $this->getFieldName()),
           $transaction);
         $this->setFieldError(pht('Required'));
       }
     }
 
     return $errors;
   }
 
   protected function isValueEmpty($value) {
     if (is_array($value)) {
       return empty($value);
     }
     return !strlen($value);
   }
 
 }