diff --git a/src/applications/project/storage/PhabricatorProject.php b/src/applications/project/storage/PhabricatorProject.php
--- a/src/applications/project/storage/PhabricatorProject.php
+++ b/src/applications/project/storage/PhabricatorProject.php
@@ -748,9 +748,75 @@
         $slug->delete();
       }
 
+      // Destroy my milestones because they cannot live without me.
+      // Do not use PhabricatorProjectQuery to avoid a circular dependency,
+      // and, to do not have a load silent fail, since these milestones do not
+      // have their parent anymore.
+      $milestones = id(new self())
+        ->loadAllWhere('parentProjectPHID = %s AND milestoneNumber IS NOT NULL',
+        $this->getPHID());
+      foreach ($milestones as $milestone) {
+        $milestone->attachParentProject($this);
+        $engine->destroyObject($milestone);
+      }
+
+      // Update my children to eventually fix holes in the tree.
+      $this->onDestroyTouchChildren(true);
+
+      // After the tree is fixed, update my parent hasSubProjects field.
+      if ($this->getParentProject()) {
+        id(new PhabricatorProjectsMembershipIndexEngineExtension())
+          ->rematerialize($this->getParentProject());
+      }
+
     $this->saveTransaction();
   }
 
+  /**
+   * On destroy, eventually bubble up my direct children, to take my place.
+   * Refresh all remaining children, to consolidate depth, path key, etc.
+   */
+  private function onDestroyTouchChildren($close_my_hole) {
+    // Micro-optimization.
+    if (!$this->supportsSubprojects() && !$this->supportsMilestones()) {
+      return;
+    }
+
+    // Get direct sub-projects and milestones and their new desired parent.
+    // We must skip my direct milestones since they are under removal.
+    // Do not use PhabricatorProjectQuery to avoid a circular dependency.
+    $query_children = new self();
+    if ($close_my_hole) {
+      $desired_parent = $this->getParentProject();
+      $children = $query_children->loadAllWhere(
+        'parentProjectPHID = %s AND milestoneNumber IS NULL',
+        $this->getPHID());
+    } else {
+      $desired_parent = $this;
+      $children = $query_children->loadAllWhere(
+        'parentProjectPHID = %s',
+        $this->getPHID());
+    }
+
+    // The desired parent PHID for my children may become NULL,
+    // when we are closing my hole but my parent it's a root-project.
+    $desired_parent_phid = null;
+    if ($desired_parent) {
+      $desired_parent_phid = $desired_parent->getPHID();
+    }
+
+    // Eventually bubble up my direct children. Update the others.
+    foreach ($children as $child) {
+      $child->attachParentProject($desired_parent);
+      $child->setParentProjectPHID($desired_parent_phid);
+      $child->setProjectPathKey(null); // Force a new path key and depth.
+      $child->save();
+
+      // Descend the tree.
+      $child->onDestroyTouchChildren(false);
+    }
+  }
+
 
 /* -(  PhabricatorFulltextInterface  )--------------------------------------- */
 
diff --git a/src/docs/user/userguide/projects.diviner b/src/docs/user/userguide/projects.diviner
--- a/src/docs/user/userguide/projects.diviner
+++ b/src/docs/user/userguide/projects.diviner
@@ -337,3 +337,126 @@
 
 Form customization also provides a powerful tool for making many policy
 management tasks easier (see @{article:User Guide: Customizing Forms}).
+
+Archiving
+=========
+
+Phorge supports the destroy (unsafe) and the archive (safe) of projects.
+
+Archiving a project (or archiving a milestone - since milestones are projects)
+is very recommended: you are encouraged in archiving a project when it stopped
+being useful, when the project reached its deadline, or when its investor was
+a scam. You might be surprised how useful it is to know which colleagues have
+worked on a certain very old archived project, which fortunately somebody
+decided to archive rather than violently destroy.
+Archiving still has sense when your boss created a nonsense project about
+how-to integrate Phorge with Doom, but now would like to hide all traces...
+still, please desist from looking for destruction, and evaluate archiving it,
+and not only for the glory of the internal documentation in your organization.
+
+The {nav icon=ban,name=Archive} action is visible to all people who
+can {nav icon=pencil,name=Edit} a project. As usual in Phorge,
+there is a confirmation dialog.
+
+After you confirm to archive a project, these things will happen:
+
+- in general, the archived project will avoid to distract people,
+  still preserving its past glory.
+- whatever mentions the tag or its hashtag, the related badge is generously
+  de-colorized or struck-through.
+- the archived project is unlisted from the active list at
+  [ /project/query/active/ ]( /project/query/active/ )
+- the archived project is de-prioritized from most search results and selectors,
+  including the top search bar, the tag pickers, etc.
+- the archived project is muted, and do not cause "watch" notifications.
+- who triggered this action is logged in the recent actions.
+
+All these consequences are reversible. You can bring a project back
+to life anytime using the {nav icon=check,name=Activate project} action.
+
+After archiving a project, all tagged objects, tagged tasks, etc. will be
+intentionally kept as-is. In particular, on tagged objects is not
+enforced any special read-only policy. This has sense if you have paid
+attention to "Policies In Depth". In short, an object can have so many tags,
+and if a specific team group closed its operations does not mean that others
+should stop working on all their tagged stuff, etc.
+
+After you presented "how amazing is Phorge about archiving projects" and
+after you distributed stickers about `#JustArchive` to all coworkers,
+it's a classic that somebody still want to "just remove the project" or
+"make it go away" or "run obliviate", etc.
+In these cases where "more censorship" is needed, you can evaluate an
+additional change in the visibility settings of that project. For example,
+the very limited visibility "show only to me" makes the project effectively
+invisible to others. Mastering the visibility policies helps a lot in making
+sure your cleanup requests are managed professionally and in a secure way,
+still allowing future auditing, when needed.
+
+At this point, if you still haven't convinced everyone to archive a specific
+project, explore the next scary and unsafe section about permanently destroying.
+
+Permanently Destroying
+======================
+
+Phorge is designed as a safe collaborative platform that rarely
+requires @{article:Permanently Destroying Data}.
+
+If you have read that article, and if you have done a backup, and if
+you have access the command line, and if you still want to permanently
+destroy a project (or a milestone), these will be the consequences:
+
+- the project is destroyed permanently from the database, forever
+  (unless you have a good backup and sufficient recover skills)
+- all objects, including tasks, repositories, wiki documents, calendars,
+  secrets, other projects, etc. to which you set visibility restrictions
+  involving that project (example: "visible to project members"),
+  these objects will be broken, and everyone will be locked out of them.
+  It means these objects will become completely invisible from the web
+  interface and API results.
+  You still have margin to recover from these particular policy problems,
+  reading the @{article:User Guide: Unlocking Objects}.
+- tagged items are generally preserved, including tasks, commits,
+  wiki documents, calendar events, repositories, etc. and these objects
+  will simply not be associated anymore with that project tag
+  (but will remain associated with other tags, of course).
+- users that are members or watchers of the destroyed project will be
+  kept in your Phorge but unassigned from that project.
+  Watchers might go crazy until they find something else to watch.
+- comments and texts wrote by users will be preserved even if they were
+  mentioning your `#project` but that hashtag will not render a link.
+  You will still be able to add that hashtag in another project,
+  to revive these links.
+- if the project has a workboard, that workboard is destroyed as well
+  (tasks in that workboard will always be kept and will remain associated
+  with other workboards, in case).
+- if the project has direct milestones, these milestones are destroyed as well
+  (note that milestones are technically projects, so, read this list
+  again aloud to understand what will happen to these milestones, and to items
+  associated to these milestones, etc.)
+- if the project has a parent project, and if that parent has no other child
+  projects anymore, that parent can be promoted to root-project again.
+  This means the members of the parent project will be editable again.
+- if the project has sub-projects, all sub-projects and all their descendant
+  sub-projects will climb the tree depth by one level, to fill the hole
+  you caused. Grandchildren become children, sons become parents,
+  etc. - a real mess for family photos.
+- you increase the risk of something completely unexpected happening,
+  such as the destruction of your entire datacenter by our
+  Slugma Pokemons out of recursion control.
+
+To permanently destroy a project, you will need to execute a command like this,
+from the root directory of the Phorge repository on your server:
+
+```
+./bin/remove destroy PHID-PROJ-abcdef123456
+```
+
+The command needs the "PHID" code of the project.
+Every project has a PHID and it can be easily retrieved in multiple ways,
+including the {nav icon=cog,name=Manage} menu of that project, hovering
+the cursor on the {nav icon=flag,name=Flag For Later} feature.
+
+This command requires a manual confirmation. Before proceeding,
+take the disclaimer seriously and read again the previous section about
+archiving projects (safe), instead of permanently destroying them (unsafe),
+to eventually change your mind.