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
@@ -2475,6 +2475,7 @@
     'PonderVote' => 'applications/ponder/constants/PonderVote.php',
     'PonderVoteEditor' => 'applications/ponder/editor/PonderVoteEditor.php',
     'PonderVoteSaveController' => 'applications/ponder/controller/PonderVoteSaveController.php',
+    'ProjectBoardTaskCard' => 'applications/project/view/ProjectBoardTaskCard.php',
     'ProjectCapabilityCreateProjects' => 'applications/project/capability/ProjectCapabilityCreateProjects.php',
     'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
     'PublishFragmentBuildStepImplementation' => 'applications/harbormaster/step/PublishFragmentBuildStepImplementation.php',
diff --git a/src/applications/maniphest/controller/ManiphestController.php b/src/applications/maniphest/controller/ManiphestController.php
--- a/src/applications/maniphest/controller/ManiphestController.php
+++ b/src/applications/maniphest/controller/ManiphestController.php
@@ -66,5 +66,4 @@
     return $view;
   }
 
-
 }
diff --git a/src/applications/maniphest/controller/ManiphestTaskEditController.php b/src/applications/maniphest/controller/ManiphestTaskEditController.php
--- a/src/applications/maniphest/controller/ManiphestTaskEditController.php
+++ b/src/applications/maniphest/controller/ManiphestTaskEditController.php
@@ -12,6 +12,7 @@
 
     $request = $this->getRequest();
     $user = $request->getUser();
+    $response_type = $request->getStr('response_type', 'task');
 
     $can_edit_assign = $this->hasApplicationCapability(
       ManiphestCapabilityEditAssign::CAPABILITY);
@@ -335,9 +336,30 @@
         }
 
         if ($request->isAjax()) {
+          switch ($response_type) {
+            case 'card':
+              $owner = null;
+              if ($task->getOwnerPHID()) {
+                $owner = id(new PhabricatorHandleQuery())
+                  ->setViewer($user)
+                  ->withPHIDs(array($task->getOwnerPHID()))
+                  ->executeOne();
+              }
+              $tasks = id(new ProjectBoardTaskCard())
+                ->setViewer($user)
+                ->setTask($task)
+                ->setOwner($owner)
+                ->setCanEdit(true)
+                ->getItem();
+              break;
+            case 'task':
+            default:
+              $tasks = $this->renderSingleTask($task);
+              break;
+          }
           return id(new AphrontAjaxResponse())->setContent(
             array(
-              'tasks' => $this->renderSingleTask($task),
+              'tasks' => $tasks,
             ));
         }
 
@@ -463,7 +485,8 @@
     $form = new AphrontFormView();
     $form
       ->setUser($user)
-      ->addHiddenInput('template', $template_id);
+      ->addHiddenInput('template', $template_id)
+      ->addHiddenInput('response_type', $response_type);
 
     if ($parent_task) {
       $form
diff --git a/src/applications/project/controller/PhabricatorProjectBoardController.php b/src/applications/project/controller/PhabricatorProjectBoardController.php
--- a/src/applications/project/controller/PhabricatorProjectBoardController.php
+++ b/src/applications/project/controller/PhabricatorProjectBoardController.php
@@ -55,11 +55,12 @@
       ->setOrderBy(ManiphestTaskQuery::ORDER_PRIORITY)
       ->execute();
     $tasks = mpull($tasks, null, 'getPHID');
+    $task_phids = array_keys($tasks);
 
-    if ($tasks) {
+    if ($task_phids) {
       $edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_COLUMN;
       $edge_query = id(new PhabricatorEdgeQuery())
-        ->withSourcePHIDs(mpull($tasks, 'getPHID'))
+        ->withSourcePHIDs($task_phids)
         ->withEdgeTypes(array($edge_type))
         ->withDestinationPHIDs(mpull($columns, 'getPHID'));
       $edge_query->execute();
@@ -77,6 +78,11 @@
       $task_map[$column_phid][] = $task_phid;
     }
 
+    $task_can_edit_map = id(new PhabricatorPolicyFilter())
+      ->setViewer($viewer)
+      ->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT))
+      ->apply($tasks);
+
     $board_id = celerity_generate_unique_node_id();
 
     $board = id(new PHUIWorkboardView())
@@ -113,7 +119,16 @@
           ));
       $task_phids = idx($task_map, $column->getPHID(), array());
       foreach (array_select_keys($tasks, $task_phids) as $task) {
-        $cards->addItem($this->renderTaskCard($task));
+        $owner = null;
+        if ($task->getOwnerPHID()) {
+          $owner = $this->handles[$task->getOwnerPHID()];
+        }
+        $cards->addItem(id(new ProjectBoardTaskCard())
+          ->setViewer($viewer)
+          ->setTask($task)
+          ->setOwner($owner)
+          ->setCanEdit($task_can_edit_map[$task->getPHID()])
+          ->getItem());
       }
       $panel->setCards($cards);
 
@@ -183,44 +198,4 @@
       ));
   }
 
-  private function renderTaskCard(ManiphestTask $task) {
-    $request = $this->getRequest();
-    $viewer = $request->getUser();
-    $handles = $this->handles;
-
-    $color_map = ManiphestTaskPriority::getColorMap();
-    $bar_color = idx($color_map, $task->getPriority(), 'grey');
-
-    // TODO: Batch this earlier on.
-    $can_edit = PhabricatorPolicyFilter::hasCapability(
-      $viewer,
-      $task,
-      PhabricatorPolicyCapability::CAN_EDIT);
-
-      $card = id(new PHUIObjectItemView())
-        ->setObjectName('T'.$task->getID())
-        ->setHeader($task->getTitle())
-        ->setGrippable($can_edit)
-        ->setHref('/T'.$task->getID())
-        ->addSigil('project-card')
-        ->setMetadata(
-          array(
-            'objectPHID' => $task->getPHID(),
-          ))
-        ->addAction(
-          id(new PHUIListItemView())
-            ->setName(pht('Edit'))
-            ->setIcon('edit')
-            ->setHref('/maniphest/task/edit/'.$task->getID().'/')
-            ->setWorkflow(true))
-        ->setBarColor($bar_color);
-
-    if ($task->getOwnerPHID()) {
-      $owner = $handles[$task->getOwnerPHID()];
-      $card->addAttribute($owner->renderLink());
-    }
-
-    return $card;
-  }
-
 }
diff --git a/src/applications/project/view/ProjectBoardTaskCard.php b/src/applications/project/view/ProjectBoardTaskCard.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/view/ProjectBoardTaskCard.php
@@ -0,0 +1,75 @@
+<?php
+
+final class ProjectBoardTaskCard {
+
+  private $viewer;
+  private $task;
+  private $owner;
+  private $canEdit;
+
+  public function setViewer(PhabricatorUser $viewer) {
+    $this->viewer = $viewer;
+    return $this;
+  }
+  public function getViewer() {
+    return $this->viewer;
+  }
+
+  public function setTask(ManiphestTask $task) {
+    $this->task = $task;
+    return $this;
+  }
+  public function getTask() {
+    return $this->task;
+  }
+
+  public function setOwner(PhabricatorObjectHandle $owner = null) {
+    $this->owner = $owner;
+    return $this;
+  }
+  public function getOwner() {
+    return $this->owner;
+  }
+
+  public function setCanEdit($can_edit) {
+    $this->canEdit = $can_edit;
+    return $this;
+  }
+  public function getCanEdit() {
+    return $this->canEdit;
+  }
+
+  public function getItem() {
+    $task = $this->getTask();
+    $owner = $this->getOwner();
+    $can_edit = $this->getCanEdit();
+
+    $color_map = ManiphestTaskPriority::getColorMap();
+    $bar_color = idx($color_map, $task->getPriority(), 'grey');
+
+    $card = id(new PHUIObjectItemView())
+      ->setObjectName('T'.$task->getID())
+      ->setHeader($task->getTitle())
+      ->setGrippable($can_edit)
+      ->setHref('/T'.$task->getID())
+      ->addSigil('project-card')
+      ->setMetadata(
+        array(
+          'objectPHID' => $task->getPHID(),
+        ))
+      ->addAction(
+        id(new PHUIListItemView())
+        ->setName(pht('Edit'))
+        ->setIcon('edit')
+        ->addSigil('edit-project-card')
+        ->setHref('/maniphest/task/edit/'.$task->getID().'/'))
+      ->setBarColor($bar_color);
+
+    if ($owner) {
+      $card->addAttribute($owner->renderLink());
+    }
+
+    return $card;
+  }
+
+}
diff --git a/webroot/rsrc/js/application/projects/behavior-project-boards.js b/webroot/rsrc/js/application/projects/behavior-project-boards.js
--- a/webroot/rsrc/js/application/projects/behavior-project-boards.js
+++ b/webroot/rsrc/js/application/projects/behavior-project-boards.js
@@ -66,4 +66,21 @@
     lists[ii].setGroup(lists);
   }
 
+  var onedit = function(card, r) {
+    var nodes = JX.$H(r.tasks).getFragment().firstChild;
+    var new_card = JX.$H(r.tasks);
+    JX.DOM.replace(card, new_card);
+  };
+
+  JX.Stratcom.listen(
+    'click',
+    ['edit-project-card'],
+    function(e) {
+      e.kill();
+      var card = e.getNode('project-card');
+      new JX.Workflow(e.getNode('tag:a').href, { 'response_type' : 'card' })
+        .setHandler(JX.bind(null, onedit, card))
+        .start();
+    });
+
 });