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
@@ -2764,6 +2764,7 @@
     'PhabricatorFileDAO' => 'applications/files/storage/PhabricatorFileDAO.php',
     'PhabricatorFileDataController' => 'applications/files/controller/PhabricatorFileDataController.php',
     'PhabricatorFileDeleteController' => 'applications/files/controller/PhabricatorFileDeleteController.php',
+    'PhabricatorFileDeleteTransaction' => 'applications/files/xaction/PhabricatorFileDeleteTransaction.php',
     'PhabricatorFileDropUploadController' => 'applications/files/controller/PhabricatorFileDropUploadController.php',
     'PhabricatorFileEditController' => 'applications/files/controller/PhabricatorFileEditController.php',
     'PhabricatorFileEditEngine' => 'applications/files/editor/PhabricatorFileEditEngine.php',
@@ -7931,6 +7932,7 @@
     'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
     'PhabricatorFileDataController' => 'PhabricatorFileController',
     'PhabricatorFileDeleteController' => 'PhabricatorFileController',
+    'PhabricatorFileDeleteTransaction' => 'PhabricatorFileTransactionType',
     'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
     'PhabricatorFileEditController' => 'PhabricatorFileController',
     'PhabricatorFileEditEngine' => 'PhabricatorEditEngine',
diff --git a/src/applications/files/controller/PhabricatorFileDeleteController.php b/src/applications/files/controller/PhabricatorFileDeleteController.php
--- a/src/applications/files/controller/PhabricatorFileDeleteController.php
+++ b/src/applications/files/controller/PhabricatorFileDeleteController.php
@@ -26,14 +26,18 @@
     }
 
     if ($request->isFormPost()) {
-      // Mark the file for deletion, save it, and schedule a worker to
-      // sweep by later and pick it up.
-      $file->setIsDeleted(true)->save();
-
-      PhabricatorWorker::scheduleTask(
-        'FileDeletionWorker',
-        array('objectPHID' => $file->getPHID()),
-        array('priority' => PhabricatorWorker::PRIORITY_BULK));
+      $xactions = array();
+
+      $xactions[] = id(new PhabricatorFileTransaction())
+        ->setTransactionType(PhabricatorFileDeleteTransaction::TRANSACTIONTYPE)
+        ->setNewValue(PhabricatorFile::STATUS_DELETED);
+
+      id(new PhabricatorFileEditor())
+        ->setActor($viewer)
+        ->setContentSourceFromRequest($request)
+        ->setContinueOnNoEffect(true)
+        ->setContinueOnMissingFields(true)
+        ->applyTransactions($file, $xactions);
 
       return id(new AphrontRedirectResponse())->setURI('/file/');
     }
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
@@ -41,6 +41,9 @@
   const METADATA_STORAGE = 'storage';
   const METADATA_INTEGRITY = 'integrity';
 
+  const STATUS_ACTIVE = 'active';
+  const STATUS_DELETED = 'deleted';
+
   protected $name;
   protected $mimeType;
   protected $byteSize;
diff --git a/src/applications/files/xaction/PhabricatorFileDeleteTransaction.php b/src/applications/files/xaction/PhabricatorFileDeleteTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/files/xaction/PhabricatorFileDeleteTransaction.php
@@ -0,0 +1,45 @@
+<?php
+
+final class PhabricatorFileDeleteTransaction
+  extends PhabricatorFileTransactionType {
+
+  const TRANSACTIONTYPE = 'file:delete';
+
+  public function generateOldValue($object) {
+    return PhabricatorFile::STATUS_ACTIVE;
+  }
+
+  public function applyInternalEffects($object, $value) {
+    $file = $object;
+    // Mark the file for deletion, save it, and schedule a worker to
+    // sweep by later and pick it up.
+    $file->setIsDeleted(true)->save();
+
+    PhabricatorWorker::scheduleTask(
+      'FileDeletionWorker',
+      array('objectPHID' => $file->getPHID()),
+      array('priority' => PhabricatorWorker::PRIORITY_BULK));
+  }
+
+  public function getIcon() {
+    return 'fa-ban';
+  }
+
+  public function getColor() {
+    return 'red';
+  }
+
+  public function getTitle() {
+    return pht(
+      '%s deleted this file.',
+      $this->renderAuthor());
+  }
+
+  public function getTitleForFeed() {
+    return pht(
+      '%s deleted %s.',
+      $this->renderAuthor(),
+      $this->renderObject());
+  }
+
+}