diff --git a/src/applications/differential/storage/DifferentialDiff.php b/src/applications/differential/storage/DifferentialDiff.php
--- a/src/applications/differential/storage/DifferentialDiff.php
+++ b/src/applications/differential/storage/DifferentialDiff.php
@@ -446,6 +446,13 @@
         $results['repository.phid'] = $repo->getPHID();
         $results['repository.vcs'] = $repo->getVersionControlSystem();
         $results['repository.uri'] = $repo->getPublicCloneURI();
+
+        // TODO: We're just hoping to get lucky. Instead, `arc` should store
+        // where it sent changes and we should only provide staging details
+        // if we reasonably believe they are accurate.
+        $staging_ref = 'refs/tags/phabricator/diff/'.$this->getID();
+        $results['repository.staging.uri'] = $repo->getStagingURI();
+        $results['repository.staging.ref'] = $staging_ref;
       }
     }
 
@@ -466,6 +473,10 @@
         pht('The version control system, either "svn", "hg" or "git".'),
       'repository.uri' =>
         pht('The URI to clone or checkout the repository from.'),
+      'repository.staging.uri' =>
+        pht('The URI of the staging repository.'),
+      'repository.staging.ref' =>
+        pht('The ref name for this change in the staging repository.'),
     );
   }
 
diff --git a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php
--- a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php
+++ b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php
@@ -295,14 +295,18 @@
     $lease_status = $lease->getStatus();
 
     switch ($lease_status) {
+      case DrydockLeaseStatus::STATUS_PENDING:
       case DrydockLeaseStatus::STATUS_ACQUIRED:
-        // TODO: Temporary failure.
-        throw new Exception(pht('Lease still activating.'));
+        throw new PhabricatorWorkerYieldException(15);
       case DrydockLeaseStatus::STATUS_ACTIVE:
         return;
       default:
-        // TODO: Permanent failure.
-        throw new Exception(pht('Lease in bad state.'));
+        throw new Exception(
+          pht(
+            'Lease ("%s") is in bad state ("%s"), expected "%s".',
+            $lease->getPHID(),
+            $lease_status,
+            DrydockLeaseStatus::STATUS_ACTIVE));
     }
   }
 
diff --git a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
--- a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
+++ b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
@@ -216,6 +216,8 @@
       $commit = idx($spec, 'commit');
       $branch = idx($spec, 'branch');
 
+      $ref = idx($spec, 'ref');
+
       if ($commit !== null) {
         $cmd[] = 'git reset --hard %s';
         $arg[] = $commit;
@@ -225,6 +227,20 @@
 
         $cmd[] = 'git reset --hard origin/%s';
         $arg[] = $branch;
+      } else if ($ref) {
+        $ref_uri = $ref['uri'];
+        $ref_ref = $ref['ref'];
+
+        $cmd[] = 'git fetch --no-tags -- %s +%s:%s';
+        $arg[] = $ref_uri;
+        $arg[] = $ref_ref;
+        $arg[] = $ref_ref;
+
+        $cmd[] = 'git checkout %s';
+        $arg[] = $ref_ref;
+
+        $cmd[] = 'git reset --hard %s';
+        $arg[] = $ref_ref;
       } else {
         $cmd[] = 'git reset --hard HEAD';
       }
diff --git a/src/applications/drydock/storage/DrydockBlueprint.php b/src/applications/drydock/storage/DrydockBlueprint.php
--- a/src/applications/drydock/storage/DrydockBlueprint.php
+++ b/src/applications/drydock/storage/DrydockBlueprint.php
@@ -107,6 +107,17 @@
     return $this->fields;
   }
 
+  public function logEvent($type, array $data = array()) {
+    $log = id(new DrydockLog())
+      ->setEpoch(PhabricatorTime::getNow())
+      ->setType($type)
+      ->setData($data);
+
+    $log->setBlueprintPHID($this->getPHID());
+
+    return $log->save();
+  }
+
 
 /* -(  Allocating Resources  )----------------------------------------------- */
 
diff --git a/src/applications/drydock/storage/DrydockLease.php b/src/applications/drydock/storage/DrydockLease.php
--- a/src/applications/drydock/storage/DrydockLease.php
+++ b/src/applications/drydock/storage/DrydockLease.php
@@ -233,18 +233,21 @@
 
     $this->openTransaction();
     try {
-      try {
-        DrydockSlotLock::acquireLocks($this->getPHID(), $this->slotLocks);
-        $this->slotLocks = array();
-      } catch (DrydockSlotLockException $ex) {
-        $this->logEvent(
-          DrydockSlotLockFailureLogType::LOGCONST,
-          array(
-            'locks' => $ex->getLockMap(),
-          ));
-        throw $ex;
-      }
+      DrydockSlotLock::acquireLocks($this->getPHID(), $this->slotLocks);
+      $this->slotLocks = array();
+    } catch (DrydockSlotLockException $ex) {
+      $this->killTransaction();
+
+      $this->logEvent(
+        DrydockSlotLockFailureLogType::LOGCONST,
+        array(
+          'locks' => $ex->getLockMap(),
+        ));
 
+      throw $ex;
+    }
+
+    try {
       $this
         ->setResourcePHID($resource->getPHID())
         ->attachResource($resource)
diff --git a/src/applications/drydock/storage/DrydockResource.php b/src/applications/drydock/storage/DrydockResource.php
--- a/src/applications/drydock/storage/DrydockResource.php
+++ b/src/applications/drydock/storage/DrydockResource.php
@@ -148,19 +148,25 @@
     }
 
     $this->openTransaction();
+
     try {
-      try {
-        DrydockSlotLock::acquireLocks($this->getPHID(), $this->slotLocks);
-        $this->slotLocks = array();
-      } catch (DrydockSlotLockException $ex) {
-        $this->logEvent(
-          DrydockSlotLockFailureLogType::LOGCONST,
-          array(
-            'locks' => $ex->getLockMap(),
-          ));
-        throw $ex;
-      }
+      DrydockSlotLock::acquireLocks($this->getPHID(), $this->slotLocks);
+      $this->slotLocks = array();
+    } catch (DrydockSlotLockException $ex) {
+      $this->killTransaction();
+
+      // NOTE: We have to log this on the blueprint, as the resource is not
+      // going to be saved so the PHID will vanish.
+      $this->getBlueprint()->logEvent(
+        DrydockSlotLockFailureLogType::LOGCONST,
+        array(
+          'locks' => $ex->getLockMap(),
+        ));
 
+      throw $ex;
+    }
+
+    try {
       $this
         ->setStatus($new_status)
         ->save();
@@ -168,6 +174,7 @@
       $this->killTransaction();
       throw $ex;
     }
+
     $this->saveTransaction();
 
     $this->isAllocated = true;
diff --git a/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php b/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php
--- a/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php
+++ b/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php
@@ -660,9 +660,10 @@
     $lease->logEvent(DrydockLeaseReleasedLogType::LOGCONST);
 
     $resource = $lease->getResource();
-    $blueprint = $resource->getBlueprint();
-
-    $blueprint->didReleaseLease($resource, $lease);
+    if ($resource) {
+      $blueprint = $resource->getBlueprint();
+      $blueprint->didReleaseLease($resource, $lease);
+    }
 
     $this->destroyLease($lease);
   }
diff --git a/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php
@@ -113,6 +113,13 @@
     $variables = $build_target->getVariables();
 
     $repository_phid = idx($variables, 'repository.phid');
+    if (!$repository_phid) {
+      throw new Exception(
+        pht(
+          'Unable to determine how to clone the repository for this '.
+          'buildable: it is not associated with a tracked repository.'));
+    }
+
     $also_phids = $build_target->getFieldValue('repositoryPHIDs');
 
     $all_phids = $also_phids;
@@ -133,8 +140,6 @@
       }
     }
 
-    $commit = idx($variables, 'repository.commit');
-
     $map = array();
 
     foreach ($also_phids as $also_phid) {
@@ -147,12 +152,33 @@
 
     $repository = $repositories[$repository_phid];
 
+    $commit = idx($variables, 'repository.commit');
+    $ref_uri = idx($variables, 'repository.staging.uri');
+    $ref_ref = idx($variables, 'repository.staging.ref');
+    if ($commit) {
+      $spec = array(
+        'commit' => $commit,
+      );
+    } else if ($ref_uri && $ref_ref) {
+      $spec = array(
+        'ref' => array(
+          'uri' => $ref_uri,
+          'ref' => $ref_ref,
+        ),
+      );
+    } else {
+      throw new Exception(
+        pht(
+          'Unable to determine how to fetch changes: this buildable does not '.
+          'identify a commit or a staging ref. You may need to configure a '.
+          'repository staging area.'));
+    }
+
     $directory = $repository->getCloneName();
     $map[$directory] = array(
       'phid' => $repository->getPHID(),
-      'commit' => $commit,
       'default' => true,
-    );
+    ) + $spec;
 
     return $map;
   }
diff --git a/src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php b/src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php
--- a/src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php
+++ b/src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php
@@ -86,15 +86,23 @@
   }
 
   protected function checkLease() {
-    if ($this->leaseOwner) {
-      $current_server_time = $this->serverTime + (time() - $this->localTime);
-      if ($current_server_time >= $this->leaseExpires) {
-        throw new Exception(
-          pht(
-            'Trying to update Task %d (%s) after lease expiration!',
-            $this->getID(),
-            $this->getTaskClass()));
-      }
+    $owner = $this->leaseOwner;
+
+    if (!$owner) {
+      return;
+    }
+
+    if ($owner == PhabricatorWorker::YIELD_OWNER) {
+      return;
+    }
+
+    $current_server_time = $this->serverTime + (time() - $this->localTime);
+    if ($current_server_time >= $this->leaseExpires) {
+      throw new Exception(
+        pht(
+          'Trying to update Task %d (%s) after lease expiration!',
+          $this->getID(),
+          $this->getTaskClass()));
     }
   }