diff --git a/src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubIssue.php b/src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubIssue.php
--- a/src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubIssue.php
+++ b/src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubIssue.php
@@ -76,9 +76,6 @@
       $ref->setAttribute('name', $body['title']);
 
       $obj = $ref->getExternalObject();
-      if ($obj->getID()) {
-        continue;
-      }
 
       $this->fillObjectFromData($obj, $result);
 
@@ -92,6 +89,19 @@
     $body = $result->getBody();
     $uri = $body['html_url'];
     $obj->setObjectURI($uri);
+
+    $title = idx($body, 'title');
+    $description = idx($body, 'body');
+
+    $created = idx($body, 'created_at');
+    $created = strtotime($created);
+
+    $state = idx($body, 'state');
+
+    $obj->setProperty('task.title', $title);
+    $obj->setProperty('task.description', $description);
+    $obj->setProperty('task.created', $created);
+    $obj->setProperty('task.state', $state);
   }
 
 }
diff --git a/src/applications/nuance/github/NuanceGitHubRawEvent.php b/src/applications/nuance/github/NuanceGitHubRawEvent.php
--- a/src/applications/nuance/github/NuanceGitHubRawEvent.php
+++ b/src/applications/nuance/github/NuanceGitHubRawEvent.php
@@ -90,6 +90,10 @@
     return null;
   }
 
+  public function getComment() {
+    return 'TODO: Actually extract comment text.';
+  }
+
   public function getURI() {
     $raw = $this->raw;
 
diff --git a/src/applications/nuance/item/NuanceGitHubEventItemType.php b/src/applications/nuance/item/NuanceGitHubEventItemType.php
--- a/src/applications/nuance/item/NuanceGitHubEventItemType.php
+++ b/src/applications/nuance/item/NuanceGitHubEventItemType.php
@@ -5,6 +5,8 @@
 
   const ITEMTYPE = 'github.event';
 
+  private $externalObject;
+
   public function getItemTypeDisplayName() {
     return pht('GitHub Event');
   }
@@ -79,29 +81,13 @@
 
     // TODO: Link up the requestor, etc.
 
-    $source = $item->getSource();
-    $token = $source->getSourceProperty('github.token');
-    $token = new PhutilOpaqueEnvelope($token);
+    $is_dirty = false;
 
-    $ref = $this->getDoorkeeperRef($item);
-    if ($ref) {
-      $ref = id(new DoorkeeperImportEngine())
-        ->setViewer($viewer)
-        ->setRefs(array($ref))
-        ->setThrowOnMissingLink(true)
-        ->setContextProperty('github.token', $token)
-        ->executeOne();
-
-      if ($ref->getSyncFailed()) {
-        $xobj = null;
-      } else {
-        $xobj = $ref->getExternalObject();
-      }
+    $xobj = $this->reloadExternalObject($item);
 
-      if ($xobj) {
-        $item->setItemProperty('doorkeeper.xobj.phid', $xobj->getPHID());
-        $is_dirty = true;
-      }
+    if ($xobj) {
+      $item->setItemProperty('doorkeeper.xobj.phid', $xobj->getPHID());
+      $is_dirty = true;
     }
 
     if ($item->getStatus() == NuanceItem::STATUS_IMPORTING) {
@@ -137,6 +123,56 @@
       ->setObjectID($full_ref);
   }
 
+  private function reloadExternalObject(NuanceItem $item, $local = false) {
+    $ref = $this->getDoorkeeperRef($item);
+    if (!$ref) {
+      return null;
+    }
+
+    $source = $item->getSource();
+    $token = $source->getSourceProperty('github.token');
+    $token = new PhutilOpaqueEnvelope($token);
+
+    $viewer = $this->getViewer();
+
+    $ref = id(new DoorkeeperImportEngine())
+      ->setViewer($viewer)
+      ->setRefs(array($ref))
+      ->setThrowOnMissingLink(true)
+      ->setContextProperty('github.token', $token)
+      ->needLocalOnly($local)
+      ->executeOne();
+
+    if ($ref->getSyncFailed()) {
+      $xobj = null;
+    } else {
+      $xobj = $ref->getExternalObject();
+    }
+
+    if ($xobj) {
+      $this->externalObject = $xobj;
+    }
+
+    return $xobj;
+  }
+
+  private function getExternalObject(NuanceItem $item) {
+    if ($this->externalObject === null) {
+      $xobj = $this->reloadExternalObject($item, $local = true);
+      if ($xobj) {
+        $this->externalObject = $xobj;
+      } else {
+        $this->externalObject = false;
+      }
+    }
+
+    if ($this->externalObject) {
+      return $this->externalObject;
+    }
+
+    return null;
+  }
+
   private function newRawEvent(NuanceItem $item) {
     $type = $item->getItemProperty('api.type');
     $raw = $item->getItemProperty('api.raw', array());
@@ -147,6 +183,15 @@
   public function getItemActions(NuanceItem $item) {
     $actions = array();
 
+    $xobj = $this->getExternalObject($item);
+    if ($xobj) {
+      $actions[] = $this->newItemAction($item, 'reload')
+        ->setName(pht('Reload from GitHub'))
+        ->setIcon('fa-refresh')
+        ->setWorkflow(true)
+        ->setRenderAsForm(true);
+    }
+
     $actions[] = $this->newItemAction($item, 'sync')
       ->setName(pht('Import to Maniphest'))
       ->setIcon('fa-anchor')
@@ -189,6 +234,7 @@
           ->appendForm($form)
           ->addCancelButton($item->getURI(), pht('Done'));
       case 'sync':
+      case 'reload':
         $item->issueCommand($viewer->getPHID(), $action);
         return id(new AphrontRedirectResponse())->setURI($item->getURI());
     }
@@ -238,9 +284,117 @@
       ->appendChild($property_list);
   }
 
-  protected function handleCommand(NuanceItem $item, $action) {
+  protected function handleCommand(
+    NuanceItem $item,
+    NuanceItemCommand $command) {
+
+    $action = $command->getCommand();
+    switch ($action) {
+      case 'sync':
+        return $this->syncItem($item, $command);
+      case 'reload':
+        $this->reloadExternalObject($item);
+        return true;
+    }
+
     return null;
   }
 
+  private function syncItem(
+    NuanceItem $item,
+    NuanceItemCommand $command) {
+
+    $xobj_phid = $item->getItemProperty('doorkeeper.xobj.phid');
+    if (!$xobj_phid) {
+      throw new Exception(
+        pht(
+          'Unable to sync: no external object PHID.'));
+    }
+
+    // TODO: Write some kind of marker to prevent double-synchronization.
+
+    $viewer = $this->getViewer();
+
+    $xobj = id(new DoorkeeperExternalObjectQuery())
+      ->setViewer($viewer)
+      ->withPHIDs(array($xobj_phid))
+      ->executeOne();
+    if (!$xobj) {
+      throw new Exception(
+        pht(
+          'Unable to sync: failed to load object "%s".',
+          $xobj_phid));
+    }
+
+    $nuance_phid = id(new PhabricatorNuanceApplication())->getPHID();
+
+    $xactions = array();
+
+    $task = id(new ManiphestTaskQuery())
+      ->setViewer($viewer)
+      ->withBridgedObjectPHIDs(array($xobj_phid))
+      ->executeOne();
+    if (!$task) {
+      $task = ManiphestTask::initializeNewTask($viewer)
+        ->setAuthorPHID($nuance_phid)
+        ->setBridgedObjectPHID($xobj_phid);
+
+      $title = $xobj->getProperty('task.title');
+      if (!strlen($title)) {
+        $title = pht('Nuance Item %d Task', $item->getID());
+      }
+
+      $description = $xobj->getProperty('task.description');
+      $created = $xobj->getProperty('task.created');
+      $state = $xobj->getProperty('task.state');
+
+      $xactions[] = id(new ManiphestTransaction())
+        ->setTransactionType(ManiphestTransaction::TYPE_TITLE)
+        ->setNewValue($title)
+        ->setDateCreated($created);
+
+      $xactions[] = id(new ManiphestTransaction())
+        ->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION)
+        ->setNewValue($description)
+        ->setDateCreated($created);
+
+      $task->setDateCreated($created);
+
+      // TODO: Synchronize state.
+    }
+
+    $event = $this->newRawEvent($item);
+    $comment = $event->getComment();
+    if (strlen($comment)) {
+      $xactions[] = id(new ManiphestTransaction())
+        ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
+        ->attachComment(
+          id(new ManiphestTransactionComment())
+            ->setContent($comment));
+    }
+
+    // TODO: Preserve the item's original source.
+    $source = PhabricatorContentSource::newForSource(
+      PhabricatorContentSource::SOURCE_DAEMON,
+      array());
+
+    // TOOD: This should really be the external source.
+    $acting_phid = $nuance_phid;
+
+    $editor = id(new ManiphestTransactionEditor())
+      ->setActor($viewer)
+      ->setActingAsPHID($acting_phid)
+      ->setContentSource($source)
+      ->setContinueOnNoEffect(true)
+      ->setContinueOnMissingFields(true);
+
+    $xactions = $editor->applyTransactions($task, $xactions);
+
+    return array(
+      'objectPHID' => $task->getPHID(),
+      'xactionPHIDs' => mpull($xactions, 'getPHID'),
+    );
+  }
+
 
 }
diff --git a/src/applications/nuance/item/NuanceItemType.php b/src/applications/nuance/item/NuanceItemType.php
--- a/src/applications/nuance/item/NuanceItemType.php
+++ b/src/applications/nuance/item/NuanceItemType.php
@@ -131,7 +131,9 @@
       ->applyTransactions($item, array($xaction));
   }
 
-  protected function handleCommand(NuanceItem $item, $action) {
+  protected function handleCommand(
+    NuanceItem $item,
+    NuanceItemCommand $command) {
     return null;
   }