diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php
--- a/src/applications/files/storage/PhabricatorFile.php
+++ b/src/applications/files/storage/PhabricatorFile.php
@@ -1414,11 +1414,33 @@
 
   /**
    * Write the policy edge between this file and some object.
+   * This method is successful even if the file is already attached.
    *
    * @param phid Object PHID to attach to.
    * @return this
    */
   public function attachToObject($phid) {
+    self::attachFileToObject($this->getPHID(), $phid);
+    return $this;
+  }
+
+  /**
+   * Write the policy edge between a file and some object.
+   * This method is successful even if the file is already attached.
+   * NOTE: Please avoid to use this static method directly.
+   *       Instead, use PhabricatorFile#attachToObject(phid).
+   *
+   * @param phid File PHID to attach from.
+   * @param phid Object PHID to attach to.
+   * @return void
+   */
+  public static function attachFileToObject($file_phid, $object_phid) {
+
+    // It can be easy to confuse the two arguments. Be strict.
+    if (phid_get_type($file_phid) !== PhabricatorFileFilePHIDType::TYPECONST) {
+      throw new Exception(pht('The first argument must be a phid of a file.'));
+    }
+
     $attachment_table = new PhabricatorFileAttachment();
     $attachment_conn = $attachment_table->establishConnection('w');
 
@@ -1432,14 +1454,12 @@
           attacherPHID = VALUES(attacherPHID),
           dateModified = VALUES(dateModified)',
       $attachment_table,
-      $phid,
-      $this->getPHID(),
+      $object_phid,
+      $file_phid,
       PhabricatorFileAttachment::MODE_ATTACH,
       null,
       PhabricatorTime::getNow(),
       PhabricatorTime::getNow());
-
-    return $this;
   }
 
 
diff --git a/src/applications/files/storage/__tests__/PhabricatorFileTestCase.php b/src/applications/files/storage/__tests__/PhabricatorFileTestCase.php
--- a/src/applications/files/storage/__tests__/PhabricatorFileTestCase.php
+++ b/src/applications/files/storage/__tests__/PhabricatorFileTestCase.php
@@ -277,6 +277,70 @@
       pht('Attached Thumbnail Visibility'));
   }
 
+  public function testFileVisibilityManually() {
+    $author = $this->generateNewTestUser();
+    $viewer = $this->generateNewTestUser();
+    $author_and_viewer = array($author, $viewer);
+
+    $engine = new PhabricatorTestStorageEngine();
+    $params = array(
+      'name' => 'test.dat',
+      'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
+      'authorPHID' => $author->getPHID(),
+      'storageEngines' => array(
+        $engine,
+      ),
+    );
+
+    $data = Filesystem::readRandomCharacters(64);
+    $file = PhabricatorFile::newFromFileData($data, $params);
+
+    // Create an object.
+    $object = ManiphestTask::initializeNewTask($author)
+      ->setTitle(pht('Test Task'))
+      ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
+      ->save();
+
+    // Test file's visibility before attachment.
+    $this->assertEqual(
+      array(
+        true,
+        false,
+      ),
+      $this->canViewFile($author_and_viewer, $file),
+      pht('File Visibility Before Being Attached'));
+
+    // Manually attach.
+    $file->attachToObject($object->getPHID());
+
+    // Test the referenced file's visibility.
+    $this->assertEqual(
+      array(
+        true,
+        true,
+      ),
+      $this->canViewFile($author_and_viewer, $file),
+      pht('File Visibility After Being Attached'));
+
+    // Try again. This should not explode.
+    $file->attachToObject($object->getPHID());
+
+    // Try again with this low-level. Again, this should not explode.
+    PhabricatorFile::attachFileToObject($file->getPHID(), $object->getPHID());
+
+    // Try again but using the wrong low-level usage.
+    $is_wrong_usage = false;
+    try {
+      PhabricatorFile::attachFileToObject($object->getPHID(), $file->getPHID());
+    } catch (Throwable $e) {
+      $is_wrong_usage = true;
+    }
+    $this->assertEqual(
+      true,
+      $is_wrong_usage,
+      pht('Check Attach Low-Level Validation'));
+  }
+
   private function canViewFile(array $users, PhabricatorFile $file) {
     $results = array();
     foreach ($users as $user) {
diff --git a/src/applications/maniphest/xaction/ManiphestTaskCoverImageTransaction.php b/src/applications/maniphest/xaction/ManiphestTaskCoverImageTransaction.php
--- a/src/applications/maniphest/xaction/ManiphestTaskCoverImageTransaction.php
+++ b/src/applications/maniphest/xaction/ManiphestTaskCoverImageTransaction.php
@@ -27,14 +27,31 @@
       return;
     }
 
+    // Generate an image transformation, usually smaller (orphan now).
     $xform_key = PhabricatorFileThumbnailTransform::TRANSFORM_WORKCARD;
     $xform = PhabricatorFileTransform::getTransformByKey($xform_key)
       ->executeTransform($file);
 
+    // Make that image transformation non-orphan.
+    id(new PhabricatorTransformedFile())
+      ->setOriginalPHID($file_phid)
+      ->setTransformedPHID($xform->getPHID())
+      ->setTransform($xform_key)
+      ->save();
+
     $object->setProperty('cover.filePHID', $file->getPHID());
     $object->setProperty('cover.thumbnailPHID', $xform->getPHID());
   }
 
+  public function applyExternalEffects($object, $value) {
+    // If the File has a Cover Image, attach that as side-effect.
+    // Otherwise, the Cover Image may be invisible to participants.
+    $file_phid = $object->getProperty('cover.filePHID');
+    if ($file_phid) {
+      PhabricatorFile::attachFileToObject($file_phid, $object->getPHID());
+    }
+  }
+
   public function getTitle() {
     $old = $this->getOldValue();
     $new = $this->getNewValue();
diff --git a/src/applications/project/controller/PhabricatorProjectCoverController.php b/src/applications/project/controller/PhabricatorProjectCoverController.php
--- a/src/applications/project/controller/PhabricatorProjectCoverController.php
+++ b/src/applications/project/controller/PhabricatorProjectCoverController.php
@@ -35,6 +35,7 @@
 
     $xactions = array();
 
+    // Set the new Cover Image.
     $xactions[] = id(new ManiphestTransaction())
       ->setTransactionType(ManiphestTaskCoverImageTransaction::TRANSACTIONTYPE)
       ->setNewValue($file->getPHID());