diff --git a/automatic_updates.install b/automatic_updates.install
index 8a2e1b5d5e8ad037bddb3dbbb8e596fdb8967334..935915f697f628e718c48460472786e0b6fe599f 100644
--- a/automatic_updates.install
+++ b/automatic_updates.install
@@ -7,7 +7,7 @@
 
 declare(strict_types = 1);
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates\Validation\StatusCheckRequirements;
 use Drupal\system\SystemManager;
 
@@ -15,7 +15,7 @@ use Drupal\system\SystemManager;
  * Implements hook_uninstall().
  */
 function automatic_updates_uninstall() {
-  \Drupal::service('automatic_updates.updater')->destroy(TRUE);
+  \Drupal::service('automatic_updates.update_stage')->destroy(TRUE);
 }
 
 /**
@@ -30,7 +30,7 @@ function automatic_updates_requirements($phase) {
 
     // Check that site has cron updates enabled or not.
     // @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
-    if (\Drupal::configFactory()->get('automatic_updates.settings')->get('cron') !== CronUpdater::DISABLED) {
+    if (\Drupal::configFactory()->get('automatic_updates.settings')->get('cron') !== CronUpdateStage::DISABLED) {
       $requirements['automatic_updates_cron'] = [
         'title' => t('Cron installs updates automatically'),
         'severity' => SystemManager::REQUIREMENT_WARNING,
diff --git a/automatic_updates.module b/automatic_updates.module
index 716cd7c9d6128fee42b88814f5f177d7015d9838..4cb6d2eaec2701a02f0a9402b087e06c23741000 100644
--- a/automatic_updates.module
+++ b/automatic_updates.module
@@ -8,7 +8,7 @@
 declare(strict_types = 1);
 
 use Drupal\automatic_updates\BatchProcessor;
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\automatic_updates\Validation\AdminStatusCheckMessages;
 use Drupal\Core\Url;
@@ -169,9 +169,9 @@ function automatic_updates_cron() {
     return;
   }
 
-  /** @var \Drupal\automatic_updates\CronUpdater $updater */
-  $updater = \Drupal::service('automatic_updates.cron_updater');
-  $updater->handleCron();
+  /** @var \Drupal\automatic_updates\CronUpdateStage $stage */
+  $stage = \Drupal::service('automatic_updates.cron_update_stage');
+  $stage->handleCron();
 
   /** @var \Drupal\automatic_updates\Validation\StatusChecker $status_checker */
   $status_checker = \Drupal::service('automatic_updates.status_checker');
@@ -184,7 +184,7 @@ function automatic_updates_cron() {
   }
 
   // Only try to send failure notifications if unattended updates are enabled.
-  if ($updater->getMode() !== CronUpdater::DISABLED) {
+  if ($stage->getMode() !== CronUpdateStage::DISABLED) {
     \Drupal::service('automatic_updates.status_check_mailer')
       ->sendFailureNotifications($last_results, $status_checker->getResults());
   }
@@ -199,12 +199,12 @@ function automatic_updates_modules_installed($modules) {
   /** @var \Drupal\automatic_updates\Validation\StatusChecker $status_checker */
   $status_checker = \Drupal::service('automatic_updates.status_checker');
   $status_checker->run();
-  /** @var \Drupal\automatic_updates\CronUpdater $cron_updater */
-  $cron_updater = \Drupal::service('automatic_updates.cron_updater');
+  /** @var \Drupal\automatic_updates\CronUpdateStage $stage */
+  $stage = \Drupal::service('automatic_updates.cron_update_stage');
   // If cron updates are disabled status check messages will not be displayed on
   // admin pages. Therefore, after installing the module the user will not be
   // alerted to any problems until they access the status report page.
-  if ($cron_updater->getMode() === CronUpdater::DISABLED) {
+  if ($stage->getMode() === CronUpdateStage::DISABLED) {
     /** @var \Drupal\automatic_updates\Validation\AdminStatusCheckMessages $status_check_messages */
     $status_check_messages = \Drupal::classResolver(AdminStatusCheckMessages::class);
     $status_check_messages->displayResultSummary();
@@ -243,15 +243,15 @@ function automatic_updates_preprocess_update_project_status(array &$variables) {
   if ($project['name'] !== 'drupal') {
     return;
   }
-  $updater = \Drupal::service('automatic_updates.updater');
+  $stage = \Drupal::service('automatic_updates.update_stage');
   $supported_target_versions = [];
   /** @var \Drupal\automatic_updates\ReleaseChooser $recommender */
   $recommender = \Drupal::service('automatic_updates.release_chooser');
   try {
-    if ($installed_minor_release = $recommender->getLatestInInstalledMinor($updater)) {
+    if ($installed_minor_release = $recommender->getLatestInInstalledMinor($stage)) {
       $supported_target_versions[] = $installed_minor_release->getVersion();
     }
-    if ($next_minor_release = $recommender->getLatestInNextMinor($updater)) {
+    if ($next_minor_release = $recommender->getLatestInNextMinor($stage)) {
       $supported_target_versions[] = $next_minor_release->getVersion();
     }
   }
diff --git a/automatic_updates.routing.yml b/automatic_updates.routing.yml
index e3f0cb67b6844157fa992b368b863000117fd5ea..4f2e477ce278e76e1939df21950ebe6f44faaed0 100644
--- a/automatic_updates.routing.yml
+++ b/automatic_updates.routing.yml
@@ -30,6 +30,6 @@ automatic_updates.finish:
 automatic_updates.cron.post_apply:
   path: '/automatic-update/cron/post-apply/{stage_id}/{installed_version}/{target_version}/{key}'
   defaults:
-    _controller: 'automatic_updates.cron_updater:handlePostApply'
+    _controller: 'automatic_updates.cron_update_stage:handlePostApply'
   requirements:
     _access_system_cron: 'TRUE'
diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml
index d0d2be5d1a3cd9dca90e30fe29e149e126e1c63d..bab735775ef53ffb9ea6d51dab8fb45430c48ec2 100644
--- a/automatic_updates.services.yml
+++ b/automatic_updates.services.yml
@@ -18,16 +18,16 @@ services:
   automatic_updates.status_check_mailer:
     class: Drupal\automatic_updates\StatusCheckMailer
   Drupal\automatic_updates\StatusCheckMailer: '@automatic_updates.status_check_mailer'
-  automatic_updates.updater:
-    class: Drupal\automatic_updates\Updater
+  automatic_updates.update_stage:
+    class: Drupal\automatic_updates\UpdateStage
     calls:
       - ['setLogger', ['@logger.channel.automatic_updates']]
-  Drupal\automatic_updates\Updater: '@automatic_updates.updater'
-  automatic_updates.cron_updater:
-    class: Drupal\automatic_updates\CronUpdater
+  Drupal\automatic_updates\UpdateStage: '@automatic_updates.update_stage'
+  automatic_updates.cron_update_stage:
+    class: Drupal\automatic_updates\CronUpdateStage
     calls:
       - ['setLogger', ['@logger.channel.automatic_updates']]
-  Drupal\automatic_updates\CronUpdater: '@automatic_updates.cron_updater'
+  Drupal\automatic_updates\CronUpdateStage: '@automatic_updates.cron_update_stage'
   automatic_updates.requested_update_validator:
     class: Drupal\automatic_updates\Validator\RequestedUpdateValidator
     tags:
diff --git a/automatic_updates_extensions/automatic_updates_extensions.services.yml b/automatic_updates_extensions/automatic_updates_extensions.services.yml
index 45cfaa4c16fe869578d4ad6f03d1f4b081c3a8e2..cae389f43256e1b78d4d6d460c64e71208a29102 100644
--- a/automatic_updates_extensions/automatic_updates_extensions.services.yml
+++ b/automatic_updates_extensions/automatic_updates_extensions.services.yml
@@ -2,9 +2,9 @@ services:
   _defaults:
     autowire: true
 
-  automatic_updates_extensions.updater:
-    class: Drupal\automatic_updates_extensions\ExtensionUpdater
-  Drupal\automatic_updates_extensions\ExtensionUpdater: '@automatic_updates_extensions.updater'
+  automatic_updates_extensions.update_stage:
+    class: Drupal\automatic_updates_extensions\ExtensionUpdateStage
+  Drupal\automatic_updates_extensions\ExtensionUpdateStage: '@automatic_updates_extensions.update_stage'
   automatic_updates_extensions.validator.target_release:
     class: Drupal\automatic_updates_extensions\Validator\UpdateReleaseValidator
     tags:
diff --git a/automatic_updates_extensions/src/BatchProcessor.php b/automatic_updates_extensions/src/BatchProcessor.php
index 9f1742301ad75085b416920d77803a8a19d8a7f9..c2af80fb328228ade22238bf0d2583c8eecc6127 100644
--- a/automatic_updates_extensions/src/BatchProcessor.php
+++ b/automatic_updates_extensions/src/BatchProcessor.php
@@ -24,13 +24,13 @@ final class BatchProcessor {
   public const STAGE_ID_SESSION_KEY = '_automatic_updates_extensions_stage_id';
 
   /**
-   * Gets the updater service.
+   * Gets the update stage service.
    *
-   * @return \Drupal\automatic_updates_extensions\ExtensionUpdater
-   *   The updater service.
+   * @return \Drupal\automatic_updates_extensions\ExtensionUpdateStage
+   *   The update stage service.
    */
-  protected static function getUpdater(): ExtensionUpdater {
-    return \Drupal::service('automatic_updates_extensions.updater');
+  protected static function getStage(): ExtensionUpdateStage {
+    return \Drupal::service('automatic_updates_extensions.update_stage');
   }
 
   /**
@@ -51,18 +51,18 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's begin() method.
+   * Calls the update stage's begin() method.
    *
    * @param string[] $project_versions
    *   The project versions to be staged in the update, keyed by package name.
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates_extensions\ExtensionUpdater::begin()
+   * @see \Drupal\automatic_updates_extensions\ExtensionUpdateStage::begin()
    */
   public static function begin(array $project_versions, array &$context): void {
     try {
-      $stage_id = static::getUpdater()->begin($project_versions);
+      $stage_id = static::getStage()->begin($project_versions);
       \Drupal::service('session')->set(static::STAGE_ID_SESSION_KEY, $stage_id);
     }
     catch (\Throwable $e) {
@@ -71,17 +71,17 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's stageVersions() method.
+   * Calls the update stage's stage() method.
    *
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::stage()
+   * @see \Drupal\automatic_updates\UpdateStage::stage()
    */
   public static function stage(array &$context): void {
     $stage_id = \Drupal::service('session')->get(static::STAGE_ID_SESSION_KEY);
     try {
-      static::getUpdater()->claim($stage_id)->stage();
+      static::getStage()->claim($stage_id)->stage();
     }
     catch (\Throwable $e) {
       static::clean($stage_id, $context);
@@ -90,18 +90,18 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's commit() method.
+   * Calls the update stage's apply() method.
    *
    * @param string $stage_id
    *   The stage ID.
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::apply()
+   * @see \Drupal\automatic_updates_extensions\ExtensionUpdateStage::apply()
    */
   public static function commit(string $stage_id, array &$context): void {
     try {
-      static::getUpdater()->claim($stage_id)->apply();
+      static::getStage()->claim($stage_id)->apply();
       // The batch system does not allow any single request to run for longer
       // than a second, so this will force the next operation to be done in a
       // new request. This helps keep the running code in as consistent a state
@@ -118,18 +118,18 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's postApply() method.
+   * Calls the update stage's postApply() method.
    *
    * @param string $stage_id
    *   The stage ID.
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::postApply()
+   * @see \Drupal\automatic_updates\UpdateStage::postApply()
    */
   public static function postApply(string $stage_id, array &$context): void {
     try {
-      static::getUpdater()->claim($stage_id)->postApply();
+      static::getStage()->claim($stage_id)->postApply();
     }
     catch (\Throwable $e) {
       static::handleException($e, $context);
@@ -137,18 +137,18 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's clean() method.
+   * Calls the update stage's destroy() method.
    *
    * @param string $stage_id
    *   The stage ID.
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::clean()
+   * @see \Drupal\automatic_updates_extensions\ExtensionUpdateStage::destroy()
    */
   public static function clean(string $stage_id, array &$context): void {
     try {
-      static::getUpdater()->claim($stage_id)->destroy();
+      static::getStage()->claim($stage_id)->destroy();
     }
     catch (\Throwable $e) {
       static::handleException($e, $context);
diff --git a/automatic_updates_extensions/src/ExtensionUpdater.php b/automatic_updates_extensions/src/ExtensionUpdateStage.php
similarity index 97%
rename from automatic_updates_extensions/src/ExtensionUpdater.php
rename to automatic_updates_extensions/src/ExtensionUpdateStage.php
index aebb4718f668cd578524d5f6828a4598249a83af..0c26b806a43af9f9cdcb91e93722b63ab950d58f 100644
--- a/automatic_updates_extensions/src/ExtensionUpdater.php
+++ b/automatic_updates_extensions/src/ExtensionUpdateStage.php
@@ -12,7 +12,7 @@ use Drupal\package_manager\ComposerInspector;
 use Drupal\package_manager\FailureMarker;
 use Drupal\package_manager\LegacyVersionUtility;
 use Drupal\package_manager\PathLocator;
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface;
 use PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface;
 use PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface;
@@ -26,10 +26,10 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  *   This class is an internal part of the module's update handling and
  *   should not be used by external code.
  */
-class ExtensionUpdater extends Stage {
+class ExtensionUpdateStage extends StageBase {
 
   /**
-   * Constructs a new ExtensionUpdater object.
+   * Constructs a new ExtensionUpdateStage object.
    *
    * @param \Drupal\package_manager\ComposerInspector $composerInspector
    *   The Composer inspector service.
diff --git a/automatic_updates_extensions/src/Form/UpdateReady.php b/automatic_updates_extensions/src/Form/UpdateReady.php
index f24ec48d3f01287a14685769ebc152c9dde5ac15..b3019276d4eaea3225f0ddba01eee54a0654e91b 100644
--- a/automatic_updates_extensions/src/Form/UpdateReady.php
+++ b/automatic_updates_extensions/src/Form/UpdateReady.php
@@ -12,7 +12,7 @@ use Drupal\package_manager\ProjectInfo;
 use Drupal\package_manager\ValidationResult;
 use Drupal\automatic_updates_extensions\BatchProcessor;
 use Drupal\automatic_updates\BatchProcessor as AutoUpdatesBatchProcessor;
-use Drupal\automatic_updates_extensions\ExtensionUpdater;
+use Drupal\automatic_updates_extensions\ExtensionUpdateStage;
 use Drupal\Core\Batch\BatchBuilder;
 use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Form\FormStateInterface;
@@ -37,8 +37,8 @@ final class UpdateReady extends UpdateFormBase {
   /**
    * Constructs a new UpdateReady object.
    *
-   * @param \Drupal\automatic_updates_extensions\ExtensionUpdater $updater
-   *   The updater service.
+   * @param \Drupal\automatic_updates_extensions\ExtensionUpdateStage $stage
+   *   The update stage service.
    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
    *   The messenger service.
    * @param \Drupal\Core\State\StateInterface $state
@@ -55,7 +55,7 @@ final class UpdateReady extends UpdateFormBase {
    *   The path locator service.
    */
   public function __construct(
-    private ExtensionUpdater $updater,
+    private ExtensionUpdateStage $stage,
     MessengerInterface $messenger,
     private StateInterface $state,
     private ModuleExtensionList $moduleList,
@@ -79,7 +79,7 @@ final class UpdateReady extends UpdateFormBase {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('automatic_updates_extensions.updater'),
+      $container->get('automatic_updates_extensions.update_stage'),
       $container->get('messenger'),
       $container->get('state'),
       $container->get('extension.list.module'),
@@ -95,7 +95,7 @@ final class UpdateReady extends UpdateFormBase {
    */
   public function buildForm(array $form, FormStateInterface $form_state, string $stage_id = NULL) {
     try {
-      $this->updater->claim($stage_id);
+      $this->stage->claim($stage_id);
     }
     catch (StageOwnershipException) {
       $this->messenger()->addError($this->t('Cannot continue the update because another Composer operation is currently in progress.'));
@@ -144,7 +144,7 @@ final class UpdateReady extends UpdateFormBase {
 
     // Don't run the status checks once the form has been submitted.
     if (!$form_state->getUserInput()) {
-      $results = $this->runStatusCheck($this->updater, $this->eventDispatcher);
+      $results = $this->runStatusCheck($this->stage, $this->eventDispatcher);
       // This will have no effect if $results is empty.
       $this->displayResults($results, $this->renderer);
       // If any errors occurred, return the form early so the user cannot
@@ -191,7 +191,7 @@ final class UpdateReady extends UpdateFormBase {
    */
   public function cancel(array &$form, FormStateInterface $form_state): void {
     try {
-      $this->updater->destroy();
+      $this->stage->destroy();
       $this->messenger()->addStatus($this->t('The update was successfully cancelled.'));
       $form_state->setRedirect('automatic_updates_extensions.report_update');
     }
@@ -209,12 +209,12 @@ final class UpdateReady extends UpdateFormBase {
   private function showUpdates(): array {
     // Get packages that were updated in the stage directory.
     $installed_packages = $this->composerInspector->getInstalledPackagesList($this->pathLocator->getProjectRoot());
-    $staged_packages = $this->composerInspector->getInstalledPackagesList($this->updater->getStageDirectory());
+    $staged_packages = $this->composerInspector->getInstalledPackagesList($this->stage->getStageDirectory());
     $updated_packages = $staged_packages->getPackagesWithDifferentVersionsIn($installed_packages);
 
     // Build a list of package names that were updated by user request.
     $updated_by_request = [];
-    foreach ($this->updater->getPackageVersions() as $group) {
+    foreach ($this->stage->getPackageVersions() as $group) {
       $updated_by_request = array_merge($updated_by_request, array_keys($group));
     }
 
diff --git a/automatic_updates_extensions/src/Form/UpdaterForm.php b/automatic_updates_extensions/src/Form/UpdaterForm.php
index 43b98725593d972f37a13077b91555d7e8abd933..e5200d3ef51da1e977628bcc56be04c4e55db9b8 100644
--- a/automatic_updates_extensions/src/Form/UpdaterForm.php
+++ b/automatic_updates_extensions/src/Form/UpdaterForm.php
@@ -6,7 +6,7 @@ namespace Drupal\automatic_updates_extensions\Form;
 
 use Drupal\automatic_updates\Form\UpdateFormBase;
 use Drupal\automatic_updates_extensions\BatchProcessor;
-use Drupal\automatic_updates_extensions\ExtensionUpdater;
+use Drupal\automatic_updates_extensions\ExtensionUpdateStage;
 use Drupal\Core\Batch\BatchBuilder;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\State\StateInterface;
@@ -37,7 +37,7 @@ final class UpdaterForm extends UpdateFormBase {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('automatic_updates_extensions.updater'),
+      $container->get('automatic_updates_extensions.update_stage'),
       $container->get('event_dispatcher'),
       $container->get('renderer'),
       $container->get('state'),
@@ -50,8 +50,8 @@ final class UpdaterForm extends UpdateFormBase {
   /**
    * Constructs a new UpdaterForm object.
    *
-   * @param \Drupal\automatic_updates_extensions\ExtensionUpdater $extensionUpdater
-   *   The extension updater service.
+   * @param \Drupal\automatic_updates_extensions\ExtensionUpdateStage $stage
+   *   The extension update stage service.
    * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
    *   The extension event dispatcher service.
    * @param \Drupal\Core\Render\RendererInterface $renderer
@@ -66,7 +66,7 @@ final class UpdaterForm extends UpdateFormBase {
    *   The path locator service.
    */
   public function __construct(
-    private ExtensionUpdater $extensionUpdater,
+    private ExtensionUpdateStage $stage,
     private EventDispatcherInterface $eventDispatcher,
     private RendererInterface $renderer,
     private StateInterface $state,
@@ -139,7 +139,7 @@ final class UpdaterForm extends UpdateFormBase {
       $results = [];
     }
     else {
-      $results = $this->runStatusCheck($this->extensionUpdater, $this->eventDispatcher);
+      $results = $this->runStatusCheck($this->stage, $this->eventDispatcher);
     }
     $this->displayResults($results, $this->renderer);
     $security_level = ValidationResult::getOverallSeverity($results);
@@ -166,7 +166,7 @@ final class UpdaterForm extends UpdateFormBase {
    */
   protected function actions(FormStateInterface $form_state): array {
     $actions = ['#type' => 'actions'];
-    if (!$this->extensionUpdater->isAvailable()) {
+    if (!$this->stage->isAvailable()) {
       // If the form has been submitted do not display this error message
       // because ::deleteExistingUpdate() may run on submit. The message will
       // still be displayed on form build if needed.
@@ -192,7 +192,7 @@ final class UpdaterForm extends UpdateFormBase {
    * Submit function to delete an existing in-progress update.
    */
   public function deleteExistingUpdate(): void {
-    $this->extensionUpdater->destroy(TRUE);
+    $this->stage->destroy(TRUE);
     $this->messenger()->addMessage($this->t("Staged update deleted"));
   }
 
diff --git a/automatic_updates_extensions/src/Validator/UpdateReleaseValidator.php b/automatic_updates_extensions/src/Validator/UpdateReleaseValidator.php
index 24c90715df61449b2a3be58ba309833222cb2bdc..09f84d46ba84accd64ef9dd4c4ff65aba586bbf3 100644
--- a/automatic_updates_extensions/src/Validator/UpdateReleaseValidator.php
+++ b/automatic_updates_extensions/src/Validator/UpdateReleaseValidator.php
@@ -7,7 +7,7 @@ namespace Drupal\automatic_updates_extensions\Validator;
 use Drupal\package_manager\ComposerInspector;
 use Drupal\package_manager\PathLocator;
 use Drupal\package_manager\ProjectInfo;
-use Drupal\automatic_updates_extensions\ExtensionUpdater;
+use Drupal\automatic_updates_extensions\ExtensionUpdateStage;
 use Drupal\package_manager\LegacyVersionUtility;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\package_manager\Event\PreCreateEvent;
@@ -89,7 +89,7 @@ final class UpdateReleaseValidator implements EventSubscriberInterface {
   public function checkRelease(PreCreateEvent $event): void {
     $stage = $event->stage;
     // This check only works with Automatic Updates Extensions.
-    if (!$stage instanceof ExtensionUpdater) {
+    if (!$stage instanceof ExtensionUpdateStage) {
       return;
     }
 
diff --git a/automatic_updates_extensions/tests/modules/automatic_updates_extensions_test_api/src/ApiController.php b/automatic_updates_extensions/tests/modules/automatic_updates_extensions_test_api/src/ApiController.php
index b59c7d8a5217409af9c7b5ff6d4fe3c91e3c01b3..66dfafd87bfdf571433e6abb3c48268778db3e74 100644
--- a/automatic_updates_extensions/tests/modules/automatic_updates_extensions_test_api/src/ApiController.php
+++ b/automatic_updates_extensions/tests/modules/automatic_updates_extensions_test_api/src/ApiController.php
@@ -23,7 +23,7 @@ class ApiController extends PackageManagerApiController {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('automatic_updates_extensions.updater'),
+      $container->get('automatic_updates_extensions.update_stage'),
       $container->get('package_manager.path_locator')
     );
   }
diff --git a/automatic_updates_extensions/tests/src/Kernel/AutomaticUpdatesExtensionsKernelTestBase.php b/automatic_updates_extensions/tests/src/Kernel/AutomaticUpdatesExtensionsKernelTestBase.php
index dfdb9359d88c2f979c4345e566b559994cc073d1..c309d8a6411a403fb82f4b604577228b27b8a222 100644
--- a/automatic_updates_extensions/tests/src/Kernel/AutomaticUpdatesExtensionsKernelTestBase.php
+++ b/automatic_updates_extensions/tests/src/Kernel/AutomaticUpdatesExtensionsKernelTestBase.php
@@ -81,14 +81,14 @@ abstract class AutomaticUpdatesExtensionsKernelTestBase extends AutomaticUpdates
    *   be passed if $expected_results is not empty.
    */
   protected function assertUpdateResults(array $project_versions, array $expected_results, string $event_class = NULL): void {
-    $updater = $this->container->get('automatic_updates_extensions.updater');
+    $stage = $this->container->get('automatic_updates_extensions.update_stage');
 
     try {
-      $updater->begin($project_versions);
-      $updater->stage();
-      $updater->apply();
-      $updater->postApply();
-      $updater->destroy();
+      $stage->begin($project_versions);
+      $stage->stage();
+      $stage->apply();
+      $stage->postApply();
+      $stage->destroy();
 
       // If we did not get an exception, ensure we didn't expect any results.
       $this->assertEmpty($expected_results);
diff --git a/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdaterTest.php b/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdateStageTest.php
similarity index 86%
rename from automatic_updates_extensions/tests/src/Kernel/ExtensionUpdaterTest.php
rename to automatic_updates_extensions/tests/src/Kernel/ExtensionUpdateStageTest.php
index 4aa016b95a95dfff469c17fd239ab5f92df36161..b2dac3b3c71f791c070fef8a029ff05d1f09e0be 100644
--- a/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdaterTest.php
+++ b/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdateStageTest.php
@@ -4,15 +4,15 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates_extensions\Kernel;
 
-use Drupal\automatic_updates_extensions\ExtensionUpdater;
+use Drupal\automatic_updates_extensions\ExtensionUpdateStage;
 use Drupal\Tests\user\Traits\UserCreationTrait;
 
 /**
- * @coversDefaultClass \Drupal\automatic_updates_extensions\ExtensionUpdater
+ * @coversDefaultClass \Drupal\automatic_updates_extensions\ExtensionUpdateStage
  * @group automatic_updates_extensions
  * @internal
  */
-class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase {
+class ExtensionUpdateStageTest extends AutomaticUpdatesExtensionsKernelTestBase {
 
   use UserCreationTrait;
 
@@ -46,7 +46,7 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase {
    * Tests that correct versions are staged after calling ::begin().
    */
   public function testCorrectVersionsStaged(): void {
-    $id = $this->container->get(ExtensionUpdater::class)->begin([
+    $id = $this->container->get(ExtensionUpdateStage::class)->begin([
       'my_module' => '9.8.1',
       // Use a legacy version number to ensure they are converted to semantic
       // version numbers which will work with the drupal.org Composer facade.
@@ -61,7 +61,7 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase {
     // Keep using the user account we created.
     $this->setCurrentUser($user);
 
-    $extension_updater = $this->container->get(ExtensionUpdater::class);
+    $stage = $this->container->get(ExtensionUpdateStage::class);
 
     // Ensure that the target package versions are what we expect.
     $expected_versions = [
@@ -72,9 +72,9 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase {
         'drupal/my_dev_module' => '1.2.0-alpha1@alpha',
       ],
     ];
-    $this->assertSame($expected_versions, $extension_updater->claim($id)->getPackageVersions());
+    $this->assertSame($expected_versions, $stage->claim($id)->getPackageVersions());
 
-    // When we call ExtensionUpdater::stage(), the stored project versions
+    // When we call ExtensionUpdateStage::stage(), the stored project versions
     // should be read from state and passed to Composer Stager's Stager service,
     // in the form of a Composer command. This is done using
     // package_manager_bypass's invocation recorder, rather than a regular mock,
@@ -102,7 +102,7 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase {
         'drupal/my_dev_module:1.2.0-alpha1@alpha',
       ],
     ];
-    $extension_updater->stage();
+    $stage->stage();
 
     $actual_arguments = $this->container->get('package_manager.stager')
       ->getInvocationArguments();
@@ -120,7 +120,7 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase {
     $this->expectException(\InvalidArgumentException::class);
     $this->expectExceptionMessage("The project contrib_profile1 cannot be updated because updating install profiles is not supported.");
 
-    $this->container->get(ExtensionUpdater::class)
+    $this->container->get(ExtensionUpdateStage::class)
       ->begin([
         'contrib_profile1' => '1.1.0',
       ]);
@@ -132,7 +132,7 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase {
   public function testNoProjectsInBegin(): void {
     $this->expectException(\InvalidArgumentException::class);
     $this->expectExceptionMessage('No projects to begin the update');
-    $this->container->get(ExtensionUpdater::class)->begin([]);
+    $this->container->get(ExtensionUpdateStage::class)->begin([]);
   }
 
   /**
@@ -141,7 +141,7 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase {
   public function testUnknownDrupalProject(): void {
     $this->expectException(\InvalidArgumentException::class);
     $this->expectExceptionMessage("The project my_module_unknown is not a Drupal project known to Composer and cannot be updated.");
-    $this->container->get(ExtensionUpdater::class)->begin([
+    $this->container->get(ExtensionUpdateStage::class)->begin([
       'my_module_unknown' => '9.8.1',
     ]);
   }
diff --git a/dictionary.txt b/dictionary.txt
index b6e9d0e36d8c61d2967ac44f88cb00707f305626..ad242b1dbe48ca398515a0c4b87d280b1344c546 100644
--- a/dictionary.txt
+++ b/dictionary.txt
@@ -1,4 +1,4 @@
-updater's
+stage's
 stager's
 syncer
 syncers
diff --git a/package_manager/src/Event/CollectIgnoredPathsEvent.php b/package_manager/src/Event/CollectIgnoredPathsEvent.php
index d0380391bc9961a70700bee2cd9be85a008d8702..3a1f5cdb75acfb0a2d57a9b3be02b936d33f5e93 100644
--- a/package_manager/src/Event/CollectIgnoredPathsEvent.php
+++ b/package_manager/src/Event/CollectIgnoredPathsEvent.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\package_manager\Event;
 
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface;
 use PhpTuf\ComposerStager\Infrastructure\Value\PathList\PathList;
 
@@ -26,7 +26,7 @@ class CollectIgnoredPathsEvent extends StageEvent implements PathListInterface {
   /**
    * {@inheritdoc}
    */
-  public function __construct(Stage $stage) {
+  public function __construct(StageBase $stage) {
     parent::__construct($stage);
     $this->pathList = new PathList([]);
   }
diff --git a/package_manager/src/Event/PostDestroyEvent.php b/package_manager/src/Event/PostDestroyEvent.php
index e92e080f32bda8e57bf97146cfac42b677603f7d..51d72b49c0727b3e5eb327be33c105d4c33b81ee 100644
--- a/package_manager/src/Event/PostDestroyEvent.php
+++ b/package_manager/src/Event/PostDestroyEvent.php
@@ -10,7 +10,7 @@ namespace Drupal\package_manager\Event;
  * If the stage is being force destroyed, $this->stage may be an object of a
  * different class than the one that originally created the stage directory.
  *
- * @see \Drupal\package_manager\Stage::destroy()
+ * @see \Drupal\package_manager\StageBase::destroy()
  */
 class PostDestroyEvent extends StageEvent {
 }
diff --git a/package_manager/src/Event/PreApplyEvent.php b/package_manager/src/Event/PreApplyEvent.php
index 1c616f3f165f4c98a88e63f4570da2ce0b567770..4642b46bb3604246f5e196007c7f98edbeb2fc74 100644
--- a/package_manager/src/Event/PreApplyEvent.php
+++ b/package_manager/src/Event/PreApplyEvent.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\package_manager\Event;
 
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 
 /**
  * Event fired before staged changes are synced to the active directory.
@@ -16,7 +16,7 @@ class PreApplyEvent extends PreOperationStageEvent {
   /**
    * Constructs a PreApplyEvent object.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage which fired this event.
    * @param string[] $ignored_paths
    *   The list of ignored paths. These will not be copied from the stage
@@ -24,7 +24,7 @@ class PreApplyEvent extends PreOperationStageEvent {
    *   directory if they exist, when the stage directory is copied back into
    *   the active directory.
    */
-  public function __construct(Stage $stage, array $ignored_paths) {
+  public function __construct(StageBase $stage, array $ignored_paths) {
     parent::__construct($stage);
     $this->excludedPaths = $ignored_paths;
   }
diff --git a/package_manager/src/Event/PreCreateEvent.php b/package_manager/src/Event/PreCreateEvent.php
index 9957606fe7243d7059867fe0f34bc411b0375863..93d6fa5b8a7f1aef724bde283edb5f2c4c581be3 100644
--- a/package_manager/src/Event/PreCreateEvent.php
+++ b/package_manager/src/Event/PreCreateEvent.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\package_manager\Event;
 
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 
 /**
  * Event fired before a stage directory is created.
@@ -16,13 +16,13 @@ class PreCreateEvent extends PreOperationStageEvent {
   /**
    * Constructs a PreCreateEvent object.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage which fired this event.
    * @param string[] $ignored_paths
    *   The list of ignored paths. These will not be copied into the stage
    *   directory when it is created.
    */
-  public function __construct(Stage $stage, array $ignored_paths) {
+  public function __construct(StageBase $stage, array $ignored_paths) {
     parent::__construct($stage);
     $this->excludedPaths = $ignored_paths;
   }
diff --git a/package_manager/src/Event/PreDestroyEvent.php b/package_manager/src/Event/PreDestroyEvent.php
index bbef216abee86a18ca58175c47193832d82619f3..e9108f7daf56bfc1ffc29cba1e89608867dd34c9 100644
--- a/package_manager/src/Event/PreDestroyEvent.php
+++ b/package_manager/src/Event/PreDestroyEvent.php
@@ -10,7 +10,7 @@ namespace Drupal\package_manager\Event;
  * If the stage is being force destroyed, $this->stage may be an object of a
  * different class than the one that originally created the stage directory.
  *
- * @see \Drupal\package_manager\Stage::destroy()
+ * @see \Drupal\package_manager\StageBase::destroy()
  */
 class PreDestroyEvent extends PreOperationStageEvent {
 }
diff --git a/package_manager/src/Event/RequireEventTrait.php b/package_manager/src/Event/RequireEventTrait.php
index fb9c3f2849c27e2f17dda3d7e566e2acb0296448..db57153c6ef8da135ffe849c4e7119427f925799 100644
--- a/package_manager/src/Event/RequireEventTrait.php
+++ b/package_manager/src/Event/RequireEventTrait.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\package_manager\Event;
 
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 
 /**
  * Common methods for pre- and post-require events.
@@ -33,7 +33,7 @@ trait RequireEventTrait {
   /**
    * Constructs the object.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage.
    * @param string[] $runtime_packages
    *   The runtime (i.e., non-dev) packages to be required, in the form
@@ -41,7 +41,7 @@ trait RequireEventTrait {
    * @param string[] $dev_packages
    *   The dev packages to be required, in the form 'vendor/name:constraint'.
    */
-  public function __construct(Stage $stage, array $runtime_packages, array $dev_packages = []) {
+  public function __construct(StageBase $stage, array $runtime_packages, array $dev_packages = []) {
     $this->runtimePackages = $runtime_packages;
     $this->devPackages = $dev_packages;
     parent::__construct($stage);
diff --git a/package_manager/src/Event/StageEvent.php b/package_manager/src/Event/StageEvent.php
index 292a843d3cece175b8bf316aeeda5c3bc7459d2a..02b40099b99262ea62dee35e4c5752b4b216425c 100644
--- a/package_manager/src/Event/StageEvent.php
+++ b/package_manager/src/Event/StageEvent.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\package_manager\Event;
 
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use Symfony\Contracts\EventDispatcher\Event;
 
 /**
@@ -15,10 +15,10 @@ abstract class StageEvent extends Event {
   /**
    * Constructs a StageEvent object.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage which fired this event.
    */
-  public function __construct(public readonly Stage $stage) {
+  public function __construct(public readonly StageBase $stage) {
   }
 
 }
diff --git a/package_manager/src/Event/StatusCheckEvent.php b/package_manager/src/Event/StatusCheckEvent.php
index 876b43a4d348df8f0105030b11f3447a2c3ee891..12a9fa294529a6bfd479dd509f61e1f290dd9748 100644
--- a/package_manager/src/Event/StatusCheckEvent.php
+++ b/package_manager/src/Event/StatusCheckEvent.php
@@ -5,7 +5,7 @@ declare(strict_types = 1);
 namespace Drupal\package_manager\Event;
 
 use Drupal\Core\StringTranslation\TranslatableMarkup;
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use Drupal\package_manager\ValidationResult;
 use Drupal\system\SystemManager;
 
@@ -41,12 +41,12 @@ class StatusCheckEvent extends PreOperationStageEvent {
   /**
    * Constructs a StatusCheckEvent object.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage which fired this event.
    * @param string[]|null $excludedPaths
    *   The list of ignored paths, or NULL if they could not be collected.
    */
-  public function __construct(Stage $stage, private ?array $excludedPaths) {
+  public function __construct(StageBase $stage, private ?array $excludedPaths) {
     parent::__construct($stage);
   }
 
diff --git a/package_manager/src/Exception/StageException.php b/package_manager/src/Exception/StageException.php
index 2d2bc8a1bafaab55874550dd69cbe02c1f750fe7..4a08542258418b7b83a1ebdefbe4694368773ffa 100644
--- a/package_manager/src/Exception/StageException.php
+++ b/package_manager/src/Exception/StageException.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\package_manager\Exception;
 
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 
 /**
  * Base class for all exceptions related to stage operations.
@@ -16,12 +16,12 @@ class StageException extends \RuntimeException {
   /**
    * Constructs a StageException object.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage.
    * @param mixed ...$arguments
    *   Additional arguments to pass to the parent constructor.
    */
-  public function __construct(public readonly Stage $stage, ...$arguments) {
+  public function __construct(public readonly StageBase $stage, ...$arguments) {
     parent::__construct(...$arguments);
   }
 
diff --git a/package_manager/src/FailureMarker.php b/package_manager/src/FailureMarker.php
index d18e011aae62c16e5cd9e56130c943592cc57bb3..2287e983450082afda60ce790320a65ddb311964 100644
--- a/package_manager/src/FailureMarker.php
+++ b/package_manager/src/FailureMarker.php
@@ -53,12 +53,12 @@ final class FailureMarker {
   /**
    * Writes data to marker file.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage.
    * @param \Drupal\Core\StringTranslation\TranslatableMarkup $message
    *   Failure message to be added.
    */
-  public function write(Stage $stage, TranslatableMarkup $message): void {
+  public function write(StageBase $stage, TranslatableMarkup $message): void {
     $data = [
       'stage_class' => get_class($stage),
       'stage_file' => (new \ReflectionObject($stage))->getFileName(),
diff --git a/package_manager/src/PackageManagerUninstallValidator.php b/package_manager/src/PackageManagerUninstallValidator.php
index e0a754684f856cb8f32853e165ee7148a085ef7f..fa81fe42752108f9921f009f0e9fb7a9c847d331 100644
--- a/package_manager/src/PackageManagerUninstallValidator.php
+++ b/package_manager/src/PackageManagerUninstallValidator.php
@@ -27,7 +27,7 @@ final class PackageManagerUninstallValidator implements ModuleUninstallValidator
    * {@inheritdoc}
    */
   public function validate($module) {
-    $stage = new Stage(
+    $stage = new class(
       $this->container->get('package_manager.path_locator'),
       $this->container->get('package_manager.beginner'),
       $this->container->get('package_manager.stager'),
@@ -37,8 +37,7 @@ final class PackageManagerUninstallValidator implements ModuleUninstallValidator
       $this->container->get('tempstore.shared'),
       $this->container->get('datetime.time'),
       $this->container->get(PathFactoryInterface::class),
-      $this->container->get('package_manager.failure_marker')
-    );
+      $this->container->get('package_manager.failure_marker')) extends StageBase {};
     if ($stage->isAvailable() || !$stage->isApplying()) {
       return [];
     }
diff --git a/package_manager/src/Stage.php b/package_manager/src/StageBase.php
similarity index 99%
rename from package_manager/src/Stage.php
rename to package_manager/src/StageBase.php
index 2a53321dc5150e3635fec4acf604f4bfcfffc329..848f656d8167b3360e4598eccae644a3585d55f6 100644
--- a/package_manager/src/Stage.php
+++ b/package_manager/src/StageBase.php
@@ -64,7 +64,7 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  * site (e.g. `/tmp/.package_managerSITE_UUID`), which is deleted when any stage
  * created by that site is destroyed.
  */
-class Stage implements LoggerAwareInterface {
+abstract class StageBase implements LoggerAwareInterface {
 
   use LoggerAwareTrait;
   use StringTranslationTrait;
diff --git a/package_manager/src/StatusCheckTrait.php b/package_manager/src/StatusCheckTrait.php
index 78e585b1d102d377d2f0139bfd4dafe2e1a4a62b..ae72f5db722121b9d0e0f494a7a35ec0bde85130 100644
--- a/package_manager/src/StatusCheckTrait.php
+++ b/package_manager/src/StatusCheckTrait.php
@@ -21,7 +21,7 @@ trait StatusCheckTrait {
   /**
    * Runs a status check for a stage and returns the results, if any.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage to run the status check for.
    * @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $event_dispatcher
    *   (optional) The event dispatcher service.
@@ -30,7 +30,7 @@ trait StatusCheckTrait {
    *   The results of the status check. If a readiness check was also done,
    *   its results will be included.
    */
-  protected function runStatusCheck(Stage $stage, EventDispatcherInterface $event_dispatcher = NULL): array {
+  protected function runStatusCheck(StageBase $stage, EventDispatcherInterface $event_dispatcher = NULL): array {
     $event_dispatcher ??= \Drupal::service('event_dispatcher');
     try {
       $ignored_paths_event = new CollectIgnoredPathsEvent($stage);
diff --git a/package_manager/tests/modules/package_manager_test_api/src/ApiController.php b/package_manager/tests/modules/package_manager_test_api/src/ApiController.php
index fb2ce00e26b81b037623ed22cbb29a5869e92d91..9178d267804dac2af051602388b4ea315bf3975d 100644
--- a/package_manager/tests/modules/package_manager_test_api/src/ApiController.php
+++ b/package_manager/tests/modules/package_manager_test_api/src/ApiController.php
@@ -7,7 +7,7 @@ namespace Drupal\package_manager_test_api;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Url;
 use Drupal\package_manager\PathLocator;
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -28,7 +28,7 @@ class ApiController extends ControllerBase {
   /**
    * The stage.
    *
-   * @var \Drupal\package_manager\Stage
+   * @var \Drupal\package_manager\StageBase
    */
   protected $stage;
 
@@ -42,12 +42,12 @@ class ApiController extends ControllerBase {
   /**
    * Constructs an ApiController object.
    *
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   The stage.
    * @param \Drupal\package_manager\PathLocator $path_locator
    *   The path locator service.
    */
-  public function __construct(Stage $stage, PathLocator $path_locator) {
+  public function __construct(StageBase $stage, PathLocator $path_locator) {
     $this->stage = $stage;
     $this->pathLocator = $path_locator;
   }
@@ -56,7 +56,7 @@ class ApiController extends ControllerBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    $stage = new Stage(
+    $stage = new ControllerStage(
       $container->get('package_manager.path_locator'),
       $container->get('package_manager.beginner'),
       $container->get('package_manager.stager'),
@@ -66,8 +66,7 @@ class ApiController extends ControllerBase {
       $container->get('tempstore.shared'),
       $container->get('datetime.time'),
       $container->get('PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface'),
-      $container->get('package_manager.failure_marker')
-    );
+      $container->get('package_manager.failure_marker'));
     return new static(
       $stage,
       $container->get('package_manager.path_locator')
@@ -158,3 +157,15 @@ class ApiController extends ControllerBase {
   }
 
 }
+
+/**
+ * Non-abstract version of StageBase.
+ *
+ * This is needed because we cannot instantiate StageBase as it's abstract, and
+ * we also can't use anonymous class because the name of anonymous class is
+ * always unique for every request which will create problem while claiming the
+ * stage as the stored lock will be different from current lock.
+ *
+ * @see \Drupal\package_manager\StageBase::claim()
+ */
+final class ControllerStage extends StageBase {}
diff --git a/package_manager/tests/src/Build/PackageUpdateTest.php b/package_manager/tests/src/Build/PackageUpdateTest.php
index 69def2b9716a5abdde2416e4c4ae125aeedb3133..85eb9f79906ffe91b8c504d6e2ece35118d46626 100644
--- a/package_manager/tests/src/Build/PackageUpdateTest.php
+++ b/package_manager/tests/src/Build/PackageUpdateTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\package_manager\Build;
 
-use Drupal\package_manager\Stage;
+use Drupal\package_manager_test_api\ControllerStage;
 
 /**
  * Tests updating packages in a stage directory.
@@ -75,7 +75,7 @@ class PackageUpdateTest extends TemplateProjectTestBase {
     // @see \Drupal\updated_module\PostApplySubscriber::postApply()
     $this->assertSame('Bravo!', $file_contents['bravo.txt']);
 
-    $this->assertExpectedStageEventsFired(Stage::class);
+    $this->assertExpectedStageEventsFired(ControllerStage::class);
   }
 
 }
diff --git a/package_manager/tests/src/Functional/FailureMarkerRequirementTest.php b/package_manager/tests/src/Functional/FailureMarkerRequirementTest.php
index c16fa178f4912930db6b9136b1ea28c935e6333e..9ac133ebee460a55115e5a0beb602bc071cf294b 100644
--- a/package_manager/tests/src/Functional/FailureMarkerRequirementTest.php
+++ b/package_manager/tests/src/Functional/FailureMarkerRequirementTest.php
@@ -7,7 +7,7 @@ namespace Drupal\Tests\package_manager\Functional;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\package_manager\FailureMarker;
 use Drupal\package_manager\PathLocator;
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\package_manager\Traits\AssertPreconditionsTrait;
 
@@ -50,7 +50,7 @@ class FailureMarkerRequirementTest extends BrowserTestBase {
 
     $failure_marker = $this->container->get(FailureMarker::class);
     $message = $this->t('Package Manager is here to wreck your day.');
-    $failure_marker->write($this->createMock(Stage::class), $message);
+    $failure_marker->write($this->createMock(StageBase::class), $message);
     $path = $failure_marker->getPath();
     $this->assertFileExists($path);
     $this->assertStringStartsWith($fake_project_root, $path);
diff --git a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php
index 33ea4650e9eaeb72e7c4b378e61dda19be36c7f2..8a6969b4876680625766fee19cfb5039d2056186 100644
--- a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php
+++ b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php
@@ -19,7 +19,7 @@ use Drupal\package_manager\FailureMarker;
 use Drupal\package_manager\PathLocator;
 use Drupal\package_manager\StatusCheckTrait;
 use Drupal\package_manager\Validator\DiskSpaceValidator;
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use Drupal\system\SystemManager;
 use Drupal\Tests\package_manager\Traits\AssertPreconditionsTrait;
 use Drupal\Tests\package_manager\Traits\FixtureManipulatorTrait;
@@ -193,10 +193,10 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
    *   (optional) The class of the event which should return the results. Must
    *   be passed if $expected_results is not empty.
    *
-   * @return \Drupal\package_manager\Stage
+   * @return \Drupal\package_manager\StageBase
    *   The stage that was used to collect the validation results.
    */
-  protected function assertResults(array $expected_results, string $event_class = NULL): Stage {
+  protected function assertResults(array $expected_results, string $event_class = NULL): StageBase {
     $stage = $this->createStage();
 
     try {
@@ -226,7 +226,7 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
    *   (optional) The test stage to use to create the status check event. If
    *   none is provided a new stage will be created.
    */
-  protected function assertStatusCheckResults(array $expected_results, Stage $stage = NULL): void {
+  protected function assertStatusCheckResults(array $expected_results, StageBase $stage = NULL): void {
     $actual_results = $this->runStatusCheck($stage ?? $this->createStage(), $this->container->get('event_dispatcher'));
     $this->assertValidationResultsEqual($expected_results, $actual_results);
   }
@@ -445,13 +445,13 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
    * @param string $event_class
    *   (optional) The event which raised the exception. Defaults to
    *   PreCreateEvent.
-   * @param \Drupal\package_manager\Stage $stage
+   * @param \Drupal\package_manager\StageBase $stage
    *   (optional) The stage which caused the exception.
    *
    * @return \Drupal\package_manager\Exception\StageEventException
    *   An exception with the given validation results.
    */
-  protected function createStageEventExceptionFromResults(array $expected_results, string $event_class = PreCreateEvent::class, Stage $stage = NULL): StageEventException {
+  protected function createStageEventExceptionFromResults(array $expected_results, string $event_class = PreCreateEvent::class, StageBase $stage = NULL): StageEventException {
     $event = new $event_class($stage ?? $this->createStage(), []);
 
     foreach ($expected_results as $result) {
@@ -467,7 +467,7 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
 /**
  * Defines a stage specifically for testing purposes.
  */
-class TestStage extends Stage {
+class TestStage extends StageBase {
 
   /**
    * {@inheritdoc}
diff --git a/package_manager/tests/src/Kernel/StageTest.php b/package_manager/tests/src/Kernel/StageBaseTest.php
similarity index 98%
rename from package_manager/tests/src/Kernel/StageTest.php
rename to package_manager/tests/src/Kernel/StageBaseTest.php
index 064b18bc8a95f2d36885932cc1fbef2505b36742..df45c0ea681ea6e8f637b73e8c012124fa467d7f 100644
--- a/package_manager/tests/src/Kernel/StageTest.php
+++ b/package_manager/tests/src/Kernel/StageBaseTest.php
@@ -29,12 +29,12 @@ use Psr\Log\LogLevel;
 use ColinODell\PsrTestLogger\TestLogger;
 
 /**
- * @coversDefaultClass \Drupal\package_manager\Stage
+ * @coversDefaultClass \Drupal\package_manager\StageBase
  * @covers \Drupal\package_manager\PackageManagerUninstallValidator
  * @group package_manager
  * @internal
  */
-class StageTest extends PackageManagerKernelTestBase {
+class StageBaseTest extends PackageManagerKernelTestBase {
 
   /**
    * {@inheritdoc}
@@ -98,7 +98,7 @@ class StageTest extends PackageManagerKernelTestBase {
    */
   public function testUncreatedGetStageDirectory(): void {
     $this->expectException(\LogicException::class);
-    $this->expectExceptionMessage('Drupal\package_manager\Stage::getStageDirectory() cannot be called because the stage has not been created or claimed.');
+    $this->expectExceptionMessage('Drupal\package_manager\StageBase::getStageDirectory() cannot be called because the stage has not been created or claimed.');
     $this->createStage()->getStageDirectory();
   }
 
diff --git a/package_manager/tests/src/Kernel/StageEventsTest.php b/package_manager/tests/src/Kernel/StageEventsTest.php
index a2b34f14b575bc82a4327011987fbeee0b69eceb..2429dbb59e4bc3c1c55308bf95f7b6a2c2cb8a79 100644
--- a/package_manager/tests/src/Kernel/StageEventsTest.php
+++ b/package_manager/tests/src/Kernel/StageEventsTest.php
@@ -38,7 +38,7 @@ class StageEventsTest extends PackageManagerKernelTestBase implements EventSubsc
   /**
    * The stage under test.
    *
-   * @var \Drupal\package_manager\Stage
+   * @var \Drupal\package_manager\StageBase
    */
   private $stage;
 
diff --git a/package_manager/tests/src/Unit/RequireEventTraitTest.php b/package_manager/tests/src/Unit/RequireEventTraitTest.php
index f477749b85fa8366fbf146da3db77c4c8335a256..85aec569fb2f67b93d1ebe9dc6fdc74bf7fa9da4 100644
--- a/package_manager/tests/src/Unit/RequireEventTraitTest.php
+++ b/package_manager/tests/src/Unit/RequireEventTraitTest.php
@@ -29,7 +29,7 @@ class RequireEventTraitTest extends UnitTestCase {
    * @dataProvider providerGetPackages
    */
   public function testGetPackages(array $runtime_packages, array $dev_packages, array $expected_runtime_packages, array $expected_dev_packages): void {
-    $stage = $this->createMock('\Drupal\package_manager\Stage');
+    $stage = $this->createMock('\Drupal\package_manager\StageBase');
 
     $events = [
       '\Drupal\package_manager\Event\PostRequireEvent',
diff --git a/package_manager/tests/src/Unit/StageTest.php b/package_manager/tests/src/Unit/StageBaseTest.php
similarity index 95%
rename from package_manager/tests/src/Unit/StageTest.php
rename to package_manager/tests/src/Unit/StageBaseTest.php
index bc5bf620e97c417753532a0a3a68d139e3ea3bf7..430c637bab476de966bc9037a0287ecf64abcb9b 100644
--- a/package_manager/tests/src/Unit/StageTest.php
+++ b/package_manager/tests/src/Unit/StageBaseTest.php
@@ -4,15 +4,15 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\package_manager\Unit;
 
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use Drupal\Tests\UnitTestCase;
 
 /**
- * @coversDefaultClass \Drupal\package_manager\Stage
+ * @coversDefaultClass \Drupal\package_manager\StageBase
  * @group package_manager
  * @internal
  */
-class StageTest extends UnitTestCase {
+class StageBaseTest extends UnitTestCase {
 
   /**
    * @covers ::validateRequirements
@@ -26,7 +26,7 @@ class StageTest extends UnitTestCase {
    * @dataProvider providerValidateRequirements
    */
   public function testValidateRequirements(?string $expected_exception, string $requirement): void {
-    $reflector = new \ReflectionClass(Stage::class);
+    $reflector = new \ReflectionClass(StageBase::class);
     $method = $reflector->getMethod('validateRequirements');
     $method->setAccessible(TRUE);
 
diff --git a/package_manager/tests/src/Unit/StageNotInActiveValidatorTest.php b/package_manager/tests/src/Unit/StageNotInActiveValidatorTest.php
index fc4f58376c2f4bc81ffda6e59bbbda90ef710ee3..eb289d96b677d1e8fb5cd1d3941c96f159db80b9 100644
--- a/package_manager/tests/src/Unit/StageNotInActiveValidatorTest.php
+++ b/package_manager/tests/src/Unit/StageNotInActiveValidatorTest.php
@@ -6,7 +6,7 @@ namespace Drupal\Tests\package_manager\Unit;
 
 use Drupal\package_manager\Event\PreCreateEvent;
 use Drupal\package_manager\PathLocator;
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use Drupal\package_manager\ValidationResult;
 use Drupal\package_manager\Validator\StageNotInActiveValidator;
 use Drupal\Tests\package_manager\Traits\ValidationTestTrait;
@@ -39,7 +39,7 @@ class StageNotInActiveValidatorTest extends UnitTestCase {
     $path_locator_prophecy->getStagingRoot()->willReturn(Path::canonicalize($staging_root));
     $path_locator_prophecy->getVendorDirectory()->willReturn('not used');
     $path_locator = $path_locator_prophecy->reveal();
-    $stage = $this->prophesize(Stage::class)->reveal();
+    $stage = $this->prophesize(StageBase::class)->reveal();
 
     $stage_not_in_active_validator = new StageNotInActiveValidator($path_locator);
     $stage_not_in_active_validator->setStringTranslation($this->getStringTranslationStub());
diff --git a/package_manager/tests/src/Unit/StatusCheckEventTest.php b/package_manager/tests/src/Unit/StatusCheckEventTest.php
index 3f16d4425868786e20f3085a33cf5640cd651e94..86ed38f0faf3d970c8e3c66e93757d6d70ae8f2b 100644
--- a/package_manager/tests/src/Unit/StatusCheckEventTest.php
+++ b/package_manager/tests/src/Unit/StatusCheckEventTest.php
@@ -5,7 +5,7 @@ declare(strict_types = 1);
 namespace Drupal\Tests\package_manager\Unit;
 
 use Drupal\package_manager\Event\StatusCheckEvent;
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -19,7 +19,7 @@ class StatusCheckEventTest extends UnitTestCase {
    */
   public function testNoPathsNoErrorException(): void {
     $event = new StatusCheckEvent(
-      $this->prophesize(Stage::class)->reveal(),
+      $this->prophesize(StageBase::class)->reveal(),
       NULL
     );
     $this->expectException(\LogicException::class);
diff --git a/src/BatchProcessor.php b/src/BatchProcessor.php
index f9efa57c4516b9a68a702ace8f17fdf135ebe05a..c4656c126f94b2cfdadf29835ecb9d063b166eb2 100644
--- a/src/BatchProcessor.php
+++ b/src/BatchProcessor.php
@@ -33,13 +33,13 @@ final class BatchProcessor {
   public const MAINTENANCE_MODE_SESSION_KEY = '_automatic_updates_maintenance_mode';
 
   /**
-   * Gets the updater service.
+   * Gets the update stage service.
    *
-   * @return \Drupal\automatic_updates\Updater
-   *   The updater service.
+   * @return \Drupal\automatic_updates\UpdateStage
+   *   The update stage service.
    */
-  protected static function getUpdater(): Updater {
-    return \Drupal::service('automatic_updates.updater');
+  protected static function getStage(): UpdateStage {
+    return \Drupal::service('automatic_updates.update_stage');
   }
 
   /**
@@ -60,18 +60,18 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's begin() method.
+   * Calls the update stage's begin() method.
    *
    * @param string[] $project_versions
    *   The project versions to be staged in the update, keyed by package name.
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::begin()
+   * @see \Drupal\automatic_updates\UpdateStage::begin()
    */
   public static function begin(array $project_versions, array &$context): void {
     try {
-      $stage_id = static::getUpdater()->begin($project_versions);
+      $stage_id = static::getStage()->begin($project_versions);
       \Drupal::service('session')->set(static::STAGE_ID_SESSION_KEY, $stage_id);
     }
     catch (\Throwable $e) {
@@ -80,17 +80,17 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's stageVersions() method.
+   * Calls the update stage's stage() method.
    *
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::stage()
+   * @see \Drupal\automatic_updates\UpdateStage::stage()
    */
   public static function stage(array &$context): void {
     $stage_id = \Drupal::service('session')->get(static::STAGE_ID_SESSION_KEY);
     try {
-      static::getUpdater()->claim($stage_id)->stage();
+      static::getStage()->claim($stage_id)->stage();
     }
     catch (\Throwable $e) {
       static::clean($stage_id, $context);
@@ -99,18 +99,18 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's commit() method.
+   * Calls the update stage's apply() method.
    *
    * @param string $stage_id
    *   The stage ID.
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::apply()
+   * @see \Drupal\automatic_updates\UpdateStage::apply()
    */
   public static function commit(string $stage_id, array &$context): void {
     try {
-      static::getUpdater()->claim($stage_id)->apply();
+      static::getStage()->claim($stage_id)->apply();
       // The batch system does not allow any single request to run for longer
       // than a second, so this will force the next operation to be done in a
       // new request. This helps keep the running code in as consistent a state
@@ -125,18 +125,18 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's postApply() method.
+   * Calls the update stage's postApply() method.
    *
    * @param string $stage_id
    *   The stage ID.
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::postApply()
+   * @see \Drupal\automatic_updates\UpdateStage::postApply()
    */
   public static function postApply(string $stage_id, array &$context): void {
     try {
-      static::getUpdater()->claim($stage_id)->postApply();
+      static::getStage()->claim($stage_id)->postApply();
     }
     catch (\Throwable $e) {
       static::handleException($e, $context);
@@ -144,18 +144,18 @@ final class BatchProcessor {
   }
 
   /**
-   * Calls the updater's clean() method.
+   * Calls the update stage's destroy() method.
    *
    * @param string $stage_id
    *   The stage ID.
    * @param array $context
    *   The current context of the batch job.
    *
-   * @see \Drupal\automatic_updates\Updater::clean()
+   * @see \Drupal\automatic_updates\UpdateStage::destroy()
    */
   public static function clean(string $stage_id, array &$context): void {
     try {
-      static::getUpdater()->claim($stage_id)->destroy();
+      static::getStage()->claim($stage_id)->destroy();
     }
     catch (\Throwable $e) {
       static::handleException($e, $context);
diff --git a/src/CronUpdater.php b/src/CronUpdateStage.php
similarity index 96%
rename from src/CronUpdater.php
rename to src/CronUpdateStage.php
index 14cb731c403ab115e2e312c7d6a9af2a25dfcd56..8568ba9a4f390b9cc86c48279f7168ec40d80e6a 100644
--- a/src/CronUpdater.php
+++ b/src/CronUpdateStage.php
@@ -35,7 +35,7 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  *   It should not be called directly, and external code should not interact
  *   with it.
  */
-class CronUpdater extends Updater {
+class CronUpdateStage extends UpdateStage {
 
   /**
    * All automatic updates are disabled.
@@ -59,7 +59,7 @@ class CronUpdater extends Updater {
   public const ALL = 'patch';
 
   /**
-   * Constructs a CronUpdater object.
+   * Constructs a CronUpdateStage object.
    *
    * @param \Drupal\automatic_updates\ReleaseChooser $releaseChooser
    *   The cron release chooser service.
@@ -153,7 +153,7 @@ class CronUpdater extends Updater {
     // only be done by ::handleCron(), which has a strong opinion about which
     // release to update to. Throwing an exception here is just to enforce this
     // boundary. To update to a specific version of core, use
-    // \Drupal\automatic_updates\Updater::begin() (which is called in
+    // \Drupal\automatic_updates\UpdateStage::begin() (which is called in
     // ::performUpdate() to start the update to the target version of core
     // chosen by ::handleCron()).
     throw new \BadMethodCallException(__METHOD__ . '() cannot be called directly.');
@@ -355,16 +355,16 @@ class CronUpdater extends Updater {
    *
    * @return string
    *   The cron update mode. Will be one of the following constants:
-   *   - \Drupal\automatic_updates\CronUpdater::DISABLED if updates during cron
-   *     are entirely disabled.
-   *   - \Drupal\automatic_updates\CronUpdater::SECURITY only security updates
-   *     can be done during cron.
-   *   - \Drupal\automatic_updates\CronUpdater::ALL if all updates are allowed
-   *     during cron.
+   *   - \Drupal\automatic_updates\CronUpdateStage::DISABLED if updates during
+   *     cron are entirely disabled.
+   *   - \Drupal\automatic_updates\CronUpdateStage::SECURITY only security
+   *     updates can be done during cron.
+   *   - \Drupal\automatic_updates\CronUpdateStage::ALL if all updates are
+   *     allowed during cron.
    */
   final public function getMode(): string {
     $mode = $this->configFactory->get('automatic_updates.settings')->get('cron');
-    return $mode ?: CronUpdater::SECURITY;
+    return $mode ?: static::SECURITY;
   }
 
 }
diff --git a/src/Form/UpdateReady.php b/src/Form/UpdateReady.php
index 023223c9b83b0b3a4f4f871970cafb170331dc67..7823dd9325e854f02ceebfbc2b4f59dcca1cf774 100644
--- a/src/Form/UpdateReady.php
+++ b/src/Form/UpdateReady.php
@@ -5,7 +5,7 @@ declare(strict_types = 1);
 namespace Drupal\automatic_updates\Form;
 
 use Drupal\automatic_updates\BatchProcessor;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\package_manager\ComposerInspector;
 use Drupal\package_manager\Exception\StageFailureMarkerException;
 use Drupal\package_manager\ValidationResult;
@@ -32,8 +32,8 @@ final class UpdateReady extends UpdateFormBase {
   /**
    * Constructs a new UpdateReady object.
    *
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater service.
+   * @param \Drupal\automatic_updates\UpdateStage $stage
+   *   The update stage service.
    * @param \Drupal\Core\State\StateInterface $state
    *   The state service.
    * @param \Drupal\Core\Extension\ModuleExtensionList $moduleList
@@ -46,7 +46,7 @@ final class UpdateReady extends UpdateFormBase {
    *   The Composer inspector service.
    */
   public function __construct(
-    protected Updater $updater,
+    protected UpdateStage $stage,
     protected StateInterface $state,
     protected ModuleExtensionList $moduleList,
     protected RendererInterface $renderer,
@@ -66,7 +66,7 @@ final class UpdateReady extends UpdateFormBase {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('automatic_updates.updater'),
+      $container->get('automatic_updates.update_stage'),
       $container->get('state'),
       $container->get('extension.list.module'),
       $container->get('renderer'),
@@ -80,7 +80,7 @@ final class UpdateReady extends UpdateFormBase {
    */
   public function buildForm(array $form, FormStateInterface $form_state, string $stage_id = NULL) {
     try {
-      $this->updater->claim($stage_id);
+      $this->stage->claim($stage_id);
     }
     catch (StageOwnershipException $e) {
       $this->messenger()->addError($e->getMessage());
@@ -94,7 +94,7 @@ final class UpdateReady extends UpdateFormBase {
     $messages = [];
 
     try {
-      $staged_core_packages = $this->composerInspector->getInstalledPackagesList($this->updater->getStageDirectory())
+      $staged_core_packages = $this->composerInspector->getInstalledPackagesList($this->stage->getStageDirectory())
         ->getCorePackages()
         ->getArrayCopy();
     }
@@ -151,7 +151,7 @@ final class UpdateReady extends UpdateFormBase {
 
     // Don't run the status checks once the form has been submitted.
     if (!$form_state->getUserInput()) {
-      $results = $this->runStatusCheck($this->updater, $this->eventDispatcher);
+      $results = $this->runStatusCheck($this->stage, $this->eventDispatcher);
       // This will have no effect if $results is empty.
       $this->displayResults($results, $this->renderer);
       // If any errors occurred, return the form early so the user cannot
@@ -198,7 +198,7 @@ final class UpdateReady extends UpdateFormBase {
    */
   public function cancel(array &$form, FormStateInterface $form_state): void {
     try {
-      $this->updater->destroy();
+      $this->stage->destroy();
       $this->messenger()->addStatus($this->t('The update was successfully cancelled.'));
       $form_state->setRedirect('update.report_update');
     }
diff --git a/src/Form/UpdaterForm.php b/src/Form/UpdaterForm.php
index f8c6b9dfd842701051c4d8af60d7a0fa056c3924..02dd0bc9c283c1597992f1f97c30c8f6c067b335 100644
--- a/src/Form/UpdaterForm.php
+++ b/src/Form/UpdaterForm.php
@@ -10,7 +10,7 @@ use Drupal\package_manager\Exception\StageFailureMarkerException;
 use Drupal\package_manager\FailureMarker;
 use Drupal\package_manager\ProjectInfo;
 use Drupal\automatic_updates\ReleaseChooser;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\update\ProjectRelease;
 use Drupal\Core\Batch\BatchBuilder;
 use Drupal\Core\Extension\ExtensionVersion;
@@ -41,8 +41,8 @@ final class UpdaterForm extends UpdateFormBase {
    *
    * @param \Drupal\Core\State\StateInterface $state
    *   The state service.
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater service.
+   * @param \Drupal\automatic_updates\UpdateStage $stage
+   *   The update stage service.
    * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
    *   The event dispatcher service.
    * @param \Drupal\automatic_updates\ReleaseChooser $releaseChooser
@@ -56,7 +56,7 @@ final class UpdaterForm extends UpdateFormBase {
    */
   public function __construct(
     protected StateInterface $state,
-    protected Updater $updater,
+    protected UpdateStage $stage,
     protected EventDispatcherInterface $eventDispatcher,
     protected ReleaseChooser $releaseChooser,
     protected RendererInterface $renderer,
@@ -77,7 +77,7 @@ final class UpdaterForm extends UpdateFormBase {
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('state'),
-      $container->get('automatic_updates.updater'),
+      $container->get('automatic_updates.update_stage'),
       $container->get('event_dispatcher'),
       $container->get('automatic_updates.release_chooser'),
       $container->get('renderer'),
@@ -97,7 +97,7 @@ final class UpdaterForm extends UpdateFormBase {
       $this->messenger()->addError($e->getMessage());
       return $form;
     }
-    if ($this->updater->isAvailable()) {
+    if ($this->stage->isAvailable()) {
       $stage_exists = FALSE;
     }
     else {
@@ -109,7 +109,7 @@ final class UpdaterForm extends UpdateFormBase {
       $stage_id = $this->getRequest()->getSession()->get(BatchProcessor::STAGE_ID_SESSION_KEY);
       if ($stage_id) {
         try {
-          $this->updater->claim($stage_id);
+          $this->stage->claim($stage_id);
           return $this->redirect('automatic_updates.confirmation_page', [
             'stage_id' => $stage_id,
           ]);
@@ -134,7 +134,7 @@ final class UpdaterForm extends UpdateFormBase {
       foreach ($support_branches as $support_branch) {
         $support_branch_extension_version = ExtensionVersion::createFromSupportBranch($support_branch);
         if ($support_branch_extension_version->getMajorVersion() === $installed_version->getMajorVersion() && $support_branch_extension_version->getMinorVersion() >= $installed_version->getMinorVersion()) {
-          $recent_release_in_minor = $this->releaseChooser->getMostRecentReleaseInMinor($this->updater, $support_branch . '0');
+          $recent_release_in_minor = $this->releaseChooser->getMostRecentReleaseInMinor($this->stage, $support_branch . '0');
           if ($recent_release_in_minor) {
             $releases[$support_branch] = $recent_release_in_minor;
           }
@@ -152,7 +152,7 @@ final class UpdaterForm extends UpdateFormBase {
       $results = [];
     }
     else {
-      $results = $this->runStatusCheck($this->updater, $this->eventDispatcher);
+      $results = $this->runStatusCheck($this->stage, $this->eventDispatcher);
     }
     $this->displayResults($results, $this->renderer);
     $project = $project_info->getProjectInfo();
@@ -323,7 +323,7 @@ final class UpdaterForm extends UpdateFormBase {
    */
   public function deleteExistingUpdate(): void {
     try {
-      $this->updater->destroy(TRUE);
+      $this->stage->destroy(TRUE);
       $this->messenger()->addMessage($this->t("Staged update deleted"));
     }
     catch (StageException $e) {
diff --git a/src/ReleaseChooser.php b/src/ReleaseChooser.php
index 04349da303290d450e27a95dfe4ad8d2fc0e2f5e..df02d95328ba9ba501e9b2bf885e54128427a96a 100644
--- a/src/ReleaseChooser.php
+++ b/src/ReleaseChooser.php
@@ -37,16 +37,16 @@ final class ReleaseChooser {
   /**
    * Returns the releases that are installable.
    *
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater that will be used to install the releases.
+   * @param \Drupal\automatic_updates\UpdateStage $stage
+   *   The update stage that will be used to install the releases.
    *
    * @return \Drupal\update\ProjectRelease[]
-   *   The releases that are installable by the given updater, according to the
-   *   version validator service.
+   *   The releases that are installable by the given update stage, according to
+   *   the version validator service.
    */
-  protected function getInstallableReleases(Updater $updater): array {
-    $filter = function (string $version) use ($updater): bool {
-      return empty($this->versionPolicyValidator->validateVersion($updater, $version));
+  protected function getInstallableReleases(UpdateStage $stage): array {
+    $filter = function (string $version) use ($stage): bool {
+      return empty($this->versionPolicyValidator->validateVersion($stage, $version));
     };
     return array_filter(
       $this->projectInfo->getInstallableReleases(),
@@ -58,8 +58,8 @@ final class ReleaseChooser {
   /**
    * Gets the most recent release in the same minor as a specified version.
    *
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater that will be used to install the release.
+   * @param \Drupal\automatic_updates\UpdateStage $stage
+   *   The update stage that will be used to install the release.
    * @param string $version
    *   The full semantic version number, which must include a patch version.
    *
@@ -69,11 +69,11 @@ final class ReleaseChooser {
    * @throws \InvalidArgumentException
    *   If the given semantic version number does not contain a patch version.
    */
-  public function getMostRecentReleaseInMinor(Updater $updater, string $version): ?ProjectRelease {
+  public function getMostRecentReleaseInMinor(UpdateStage $stage, string $version): ?ProjectRelease {
     if (static::getPatchVersion($version) === NULL) {
       throw new \InvalidArgumentException("The version number $version does not contain a patch version");
     }
-    $releases = $this->getInstallableReleases($updater);
+    $releases = $this->getInstallableReleases($stage);
     foreach ($releases as $release) {
       // Checks if the release is in the same minor as the currently installed
       // version. For example, if the current version is 9.8.0 then the
@@ -102,15 +102,15 @@ final class ReleaseChooser {
    * This will only return a release if it passes the ::isValidVersion() method
    * of the version validator service injected into this class.
    *
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater which will install the release.
+   * @param \Drupal\automatic_updates\UpdateStage $stage
+   *   The update stage which will install the release.
    *
    * @return \Drupal\update\ProjectRelease|null
    *   The latest release in the currently installed minor, if any, otherwise
    *   NULL.
    */
-  public function getLatestInInstalledMinor(Updater $updater): ?ProjectRelease {
-    return $this->getMostRecentReleaseInMinor($updater, $this->getInstalledVersion());
+  public function getLatestInInstalledMinor(UpdateStage $stage): ?ProjectRelease {
+    return $this->getMostRecentReleaseInMinor($stage, $this->getInstalledVersion());
   }
 
   /**
@@ -119,16 +119,16 @@ final class ReleaseChooser {
    * This will only return a release if it passes the ::isValidVersion() method
    * of the version validator service injected into this class.
    *
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater which will install the release.
+   * @param \Drupal\automatic_updates\UpdateStage $stage
+   *   The update stage which will install the release.
    *
    * @return \Drupal\update\ProjectRelease|null
    *   The latest release in the next minor, if any, otherwise NULL.
    */
-  public function getLatestInNextMinor(Updater $updater): ?ProjectRelease {
+  public function getLatestInNextMinor(UpdateStage $stage): ?ProjectRelease {
     $installed_version = ExtensionVersion::createFromVersionString($this->getInstalledVersion());
     $next_minor = $installed_version->getMajorVersion() . '.' . (((int) $installed_version->getMinorVersion()) + 1) . '.0';
-    return $this->getMostRecentReleaseInMinor($updater, $next_minor);
+    return $this->getMostRecentReleaseInMinor($stage, $next_minor);
   }
 
 }
diff --git a/src/Updater.php b/src/UpdateStage.php
similarity index 98%
rename from src/Updater.php
rename to src/UpdateStage.php
index d1c47a80cc4bbdcc7ac917b5d59cdef4cfd6fccd..a542b2a7d11c47fc5e66c1e52480eedfe12f4b52 100644
--- a/src/Updater.php
+++ b/src/UpdateStage.php
@@ -11,7 +11,7 @@ use Drupal\Core\TempStore\SharedTempStoreFactory;
 use Drupal\package_manager\ComposerInspector;
 use Drupal\package_manager\FailureMarker;
 use Drupal\package_manager\PathLocator;
-use Drupal\package_manager\Stage;
+use Drupal\package_manager\StageBase;
 use PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface;
 use PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface;
 use PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface;
@@ -26,10 +26,10 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  * in the project-level composer.json. If neither package is directly required
  * in the project-level composer.json, a requirement will be added.
  */
-class Updater extends Stage {
+class UpdateStage extends StageBase {
 
   /**
-   * Constructs a new Updater object.
+   * Constructs a new UpdateStage object.
    *
    * @param \Drupal\package_manager\ComposerInspector $composerInspector
    *   The Composer inspector service.
diff --git a/src/Validation/AdminStatusCheckMessages.php b/src/Validation/AdminStatusCheckMessages.php
index a187e31f698fa8a5dc3745e4fa3d7c6af96614b0..4098fe870ae5f5b7942dea9a8bfdcc7d552efe49 100644
--- a/src/Validation/AdminStatusCheckMessages.php
+++ b/src/Validation/AdminStatusCheckMessages.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\automatic_updates\Validation;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Messenger\MessengerTrait;
@@ -45,8 +45,8 @@ final class AdminStatusCheckMessages implements ContainerInjectionInterface {
    *   The current user.
    * @param \Drupal\Core\Routing\CurrentRouteMatch $currentRouteMatch
    *   The current route match.
-   * @param \Drupal\automatic_updates\CronUpdater $cronUpdater
-   *   The cron updater service.
+   * @param \Drupal\automatic_updates\CronUpdateStage $stage
+   *   The cron update stage service.
    * @param \Drupal\Core\Render\RendererInterface $renderer
    *   The renderer service.
    */
@@ -55,7 +55,7 @@ final class AdminStatusCheckMessages implements ContainerInjectionInterface {
     protected AdminContext $adminContext,
     protected AccountProxyInterface $currentUser,
     protected CurrentRouteMatch $currentRouteMatch,
-    protected CronUpdater $cronUpdater,
+    protected CronUpdateStage $stage,
     protected RendererInterface $renderer
   ) {}
 
@@ -68,7 +68,7 @@ final class AdminStatusCheckMessages implements ContainerInjectionInterface {
       $container->get('router.admin_context'),
       $container->get('current_user'),
       $container->get('current_route_match'),
-      $container->get('automatic_updates.cron_updater'),
+      $container->get('automatic_updates.cron_update_stage'),
       $container->get('renderer')
     );
   }
@@ -106,7 +106,7 @@ final class AdminStatusCheckMessages implements ContainerInjectionInterface {
   protected function displayResultsOnCurrentPage(): bool {
     // If updates will not run during cron then we don't need to show the
     // status checks on admin pages.
-    if ($this->cronUpdater->getMode() === CronUpdater::DISABLED) {
+    if ($this->stage->getMode() === CronUpdateStage::DISABLED) {
       return FALSE;
     }
 
diff --git a/src/Validation/StatusChecker.php b/src/Validation/StatusChecker.php
index e7f74502e00875bf0fbf71f0e1bca51acd574bdb..7a325c517093b30ee28e554e6ce7b2191731519c 100644
--- a/src/Validation/StatusChecker.php
+++ b/src/Validation/StatusChecker.php
@@ -4,12 +4,12 @@ declare(strict_types = 1);
 
 namespace Drupal\automatic_updates\Validation;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates\StatusCheckMailer;
 use Drupal\Core\Config\ConfigCrudEvent;
 use Drupal\Core\Config\ConfigEvents;
 use Drupal\package_manager\StatusCheckTrait;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\Component\Datetime\TimeInterface;
 use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
 use Drupal\package_manager\Event\PostApplyEvent;
@@ -39,10 +39,10 @@ final class StatusChecker implements EventSubscriberInterface {
    *   The time service.
    * @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $eventDispatcher
    *   The event dispatcher service.
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater service.
-   * @param \Drupal\automatic_updates\CronUpdater $cronUpdater
-   *   The cron updater service.
+   * @param \Drupal\automatic_updates\UpdateStage $updateStage
+   *   The update stage service.
+   * @param \Drupal\automatic_updates\CronUpdateStage $cronUpdateStage
+   *   The cron update stage service.
    * @param int $resultsTimeToLive
    *   The number of hours to store results.
    */
@@ -50,8 +50,8 @@ final class StatusChecker implements EventSubscriberInterface {
     KeyValueExpirableFactoryInterface $key_value_expirable_factory,
     protected TimeInterface $time,
     protected EventDispatcherInterface $eventDispatcher,
-    protected Updater $updater,
-    protected CronUpdater $cronUpdater,
+    protected UpdateStage $updateStage,
+    protected CronUpdateStage $cronUpdateStage,
     protected int $resultsTimeToLive,
   ) {
     $this->keyValueExpirable = $key_value_expirable_factory->get('automatic_updates');
@@ -63,14 +63,14 @@ final class StatusChecker implements EventSubscriberInterface {
    * @return $this
    */
   public function run(): self {
-    // If updates will run during cron, use the cron updater service provided by
-    // this module. This will allow validators to run specific validation for
-    // conditions that only affect cron updates.
-    if ($this->cronUpdater->getMode() === CronUpdater::DISABLED) {
-      $stage = $this->updater;
+    // If updates will run during cron, use the cron update stage service
+    // provided by this module. This will allow validators to run specific
+    // validation for conditions that only affect cron updates.
+    if ($this->cronUpdateStage->getMode() === CronUpdateStage::DISABLED) {
+      $stage = $this->updateStage;
     }
     else {
-      $stage = $this->cronUpdater;
+      $stage = $this->cronUpdateStage;
     }
     $results = $this->runStatusCheck($stage, $this->eventDispatcher);
 
@@ -158,7 +158,7 @@ final class StatusChecker implements EventSubscriberInterface {
       // are enabled. If notifications were previously disabled but have been
       // re-enabled, or their sensitivity level has changed, clear the stored
       // results so that we'll send accurate notifications next time cron runs.
-      if ($event->isChanged('cron') && $config->getOriginal('cron') === CronUpdater::DISABLED) {
+      if ($event->isChanged('cron') && $config->getOriginal('cron') === CronUpdateStage::DISABLED) {
         $this->clearStoredResults();
       }
       elseif ($event->isChanged('status_check_mail') && $config->get('status_check_mail') !== StatusCheckMailer::DISABLED) {
diff --git a/src/Validator/CronFrequencyValidator.php b/src/Validator/CronFrequencyValidator.php
index 2d669e42e1fbf0b3f7e8b9e8c733a51f1b9748db..efe167ecdf1ca3442ed74c49a75a60d64cf9d4f6 100644
--- a/src/Validator/CronFrequencyValidator.php
+++ b/src/Validator/CronFrequencyValidator.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\automatic_updates\Validator;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\Component\Datetime\TimeInterface;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -65,8 +65,6 @@ class CronFrequencyValidator implements EventSubscriberInterface {
    *   The state service.
    * @param \Drupal\Component\Datetime\TimeInterface $time
    *   The time service.
-   * @param \Drupal\automatic_updates\CronUpdater $cronUpdater
-   *   The cron updater service.
    * @param \Drupal\Core\Lock\LockBackendInterface $lock
    *   The lock service.
    */
@@ -75,7 +73,6 @@ class CronFrequencyValidator implements EventSubscriberInterface {
     protected ModuleHandlerInterface $moduleHandler,
     protected StateInterface $state,
     protected TimeInterface $time,
-    protected CronUpdater $cronUpdater,
     protected LockBackendInterface $lock,
   ) {}
 
@@ -87,12 +84,12 @@ class CronFrequencyValidator implements EventSubscriberInterface {
    */
   public function checkCronFrequency(StatusCheckEvent $event): void {
     // We only want to do this check if the stage belongs to Automatic Updates.
-    if (!$event->stage instanceof CronUpdater) {
+    if (!$event->stage instanceof CronUpdateStage) {
       return;
     }
     // If automatic updates are disabled during cron, there's nothing we need
     // to validate.
-    if ($this->cronUpdater->getMode() === CronUpdater::DISABLED) {
+    if ($event->stage->getMode() === CronUpdateStage::DISABLED) {
       return;
     }
     elseif ($this->moduleHandler->moduleExists('automated_cron')) {
diff --git a/src/Validator/CronServerValidator.php b/src/Validator/CronServerValidator.php
index 80ebc17434c81ba55573d9a293a23b0d227a4138..125a225a5eb2b1fe288cda0fb488496691eb5361 100644
--- a/src/Validator/CronServerValidator.php
+++ b/src/Validator/CronServerValidator.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\automatic_updates\Validator;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
@@ -70,7 +70,7 @@ final class CronServerValidator implements EventSubscriberInterface {
    *   The event object.
    */
   public function checkServer(PreOperationStageEvent $event): void {
-    if (!$event->stage instanceof CronUpdater) {
+    if (!$event->stage instanceof CronUpdateStage) {
       return;
     }
 
diff --git a/src/Validator/RequestedUpdateValidator.php b/src/Validator/RequestedUpdateValidator.php
index ffed086bdbf2c96378eaf78b030e70f9f4617ba2..1315063312742ae07ed7cf39bb6398d0493c03c4 100644
--- a/src/Validator/RequestedUpdateValidator.php
+++ b/src/Validator/RequestedUpdateValidator.php
@@ -5,7 +5,7 @@ declare(strict_types = 1);
 namespace Drupal\automatic_updates\Validator;
 
 use Composer\Semver\Semver;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\package_manager\ComposerInspector;
 use Drupal\package_manager\Event\PreApplyEvent;
@@ -40,7 +40,7 @@ class RequestedUpdateValidator implements EventSubscriberInterface {
    */
   public function checkRequestedStagedVersion(PreApplyEvent $event): void {
     $stage = $event->stage;
-    if (!($stage instanceof Updater)) {
+    if (!($stage instanceof UpdateStage)) {
       return;
     }
     $requested_package_versions = $stage->getPackageVersions();
diff --git a/src/Validator/ScaffoldFilePermissionsValidator.php b/src/Validator/ScaffoldFilePermissionsValidator.php
index 90ddef01b854d5c41eb6932e60638e0002ff89b4..854092c296c238a3ef4897a3e31dd25b2988476b 100644
--- a/src/Validator/ScaffoldFilePermissionsValidator.php
+++ b/src/Validator/ScaffoldFilePermissionsValidator.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\automatic_updates\Validator;
 
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\package_manager\ComposerInspector;
 use Drupal\package_manager\Event\PreApplyEvent;
@@ -44,7 +44,7 @@ final class ScaffoldFilePermissionsValidator implements EventSubscriberInterface
    */
   public function validate(PreOperationStageEvent $event): void {
     // We only want to do this check if the stage belongs to Automatic Updates.
-    if (!$event->stage instanceof Updater) {
+    if (!$event->stage instanceof UpdateStage) {
       return;
     }
     $paths = [];
diff --git a/src/Validator/StagedDatabaseUpdateValidator.php b/src/Validator/StagedDatabaseUpdateValidator.php
index 90c3d5018f66345f5282b632a1c6c60658babd49..09b52a76a92dfd2c2708f648e52375c4a1b25c80 100644
--- a/src/Validator/StagedDatabaseUpdateValidator.php
+++ b/src/Validator/StagedDatabaseUpdateValidator.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\automatic_updates\Validator;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\package_manager\Event\PreApplyEvent;
 use Drupal\package_manager\Validator\StagedDBUpdateValidator;
@@ -39,7 +39,7 @@ class StagedDatabaseUpdateValidator implements EventSubscriberInterface {
    */
   public function checkUpdateHooks(PreApplyEvent $event): void {
     $stage = $event->stage;
-    if (!$stage instanceof CronUpdater) {
+    if (!$stage instanceof CronUpdateStage) {
       return;
     }
 
diff --git a/src/Validator/StagedProjectsValidator.php b/src/Validator/StagedProjectsValidator.php
index 201870feb45e2138656b79800b457ccb0c029816..c0f94fcf496bd1344a83f14cfca3df263ff48707 100644
--- a/src/Validator/StagedProjectsValidator.php
+++ b/src/Validator/StagedProjectsValidator.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\automatic_updates\Validator;
 
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\package_manager\ComposerInspector;
 use Drupal\package_manager\Event\PreApplyEvent;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
@@ -44,7 +44,7 @@ final class StagedProjectsValidator implements EventSubscriberInterface {
   public function validateStagedProjects(PreApplyEvent $event): void {
     $stage = $event->stage;
     // We only want to do this check if the stage belongs to Automatic Updates.
-    if (!$stage instanceof Updater) {
+    if (!$stage instanceof UpdateStage) {
       return;
     }
 
diff --git a/src/Validator/VersionPolicyValidator.php b/src/Validator/VersionPolicyValidator.php
index 197c8ea7be3397223e6bb29373e6e7d9167a0d71..998da5a876c6c58e59ca715fc746d21f00840061 100644
--- a/src/Validator/VersionPolicyValidator.php
+++ b/src/Validator/VersionPolicyValidator.php
@@ -4,12 +4,12 @@ declare(strict_types = 1);
 
 namespace Drupal\automatic_updates\Validator;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\package_manager\ComposerInspector;
 use Drupal\package_manager\Event\StatusCheckEvent;
 use Drupal\package_manager\PathLocator;
 use Drupal\package_manager\ProjectInfo;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\automatic_updates\Validator\VersionPolicy\ForbidDowngrade;
 use Drupal\automatic_updates\Validator\VersionPolicy\ForbidMinorUpdates;
 use Drupal\automatic_updates\Validator\VersionPolicy\MajorVersionMatch;
@@ -57,8 +57,8 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
   /**
    * Validates a target version of Drupal core.
    *
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater which will perform the update.
+   * @param \Drupal\automatic_updates\UpdateStage $stage
+   *   The update stage which will perform the update.
    * @param string|null $target_version
    *   The target version of Drupal core, or NULL if it is not known.
    *
@@ -68,7 +68,7 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
    *
    * @see \Drupal\automatic_updates\Validator\VersionPolicy\RuleBase::validate()
    */
-  public function validateVersion(Updater $updater, ?string $target_version): array {
+  public function validateVersion(UpdateStage $stage, ?string $target_version): array {
     // Check that the installed version of Drupal isn't a dev snapshot.
     $rules = [
       ForbidDevSnapshot::class,
@@ -85,10 +85,10 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
     }
 
     // If this is a cron update, we may need to do additional checks.
-    if ($updater instanceof CronUpdater) {
-      $mode = $updater->getMode();
+    if ($stage instanceof CronUpdateStage) {
+      $mode = $stage->getMode();
 
-      if ($mode !== CronUpdater::DISABLED) {
+      if ($mode !== CronUpdateStage::DISABLED) {
         // If cron updates are enabled, the installed version must be stable;
         // no alphas, betas, or RCs.
         $rules[] = StableReleaseInstalled::class;
@@ -104,7 +104,7 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
 
           // If only security updates are allowed during cron, the target
           // version must be a security release.
-          if ($mode === CronUpdater::SECURITY) {
+          if ($mode === CronUpdateStage::SECURITY) {
             $rules[] = TargetSecurityRelease::class;
           }
         }
@@ -117,7 +117,7 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
     }
 
     $installed_version = $this->getInstalledVersion();
-    $available_releases = $this->getAvailableReleases($updater);
+    $available_releases = $this->getAvailableReleases($stage);
 
     // Invoke each rule in the order that they were added to $rules, stopping
     // when one returns error messages.
@@ -144,7 +144,7 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
     $stage = $event->stage;
 
     // Only do these checks for automatic updates.
-    if (!$stage instanceof Updater) {
+    if (!$stage instanceof UpdateStage) {
       return;
     }
     $target_version = $this->getTargetVersion($event);
@@ -181,17 +181,17 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
    * @throws \LogicException
    *   Thrown if the target version cannot be determined due to unexpected
    *   conditions. This can happen if, during a stage life cycle event (i.e.,
-   *   NOT a status check), the event or updater does not have a list of desired
-   *   package versions, or the list of package versions does not include any
-   *   Drupal core packages.
+   *   NOT a status check), the event or update stage does not have a list of
+   *   desired package versions, or the list of package versions does not
+   *   include any Drupal core packages.
    */
   private function getTargetVersion(StageEvent $event): ?string {
-    $updater = $event->stage;
+    $stage = $event->stage;
 
     // If we're not doing a status check, we expect the stage to have been
     // created, and the requested package versions recorded.
     if (!$event instanceof StatusCheckEvent) {
-      $package_versions = $updater->getPackageVersions()['production'];
+      $package_versions = $stage->getPackageVersions()['production'];
     }
 
     $unknown_target = new \LogicException('The target version of Drupal core could not be determined.');
@@ -207,8 +207,8 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
       }
     }
     elseif ($event instanceof StatusCheckEvent) {
-      if ($updater instanceof CronUpdater) {
-        $target_release = $updater->getTargetRelease();
+      if ($stage instanceof CronUpdateStage) {
+        $target_release = $stage->getTargetRelease();
         if ($target_release) {
           return $target_release->getVersion();
         }
@@ -220,23 +220,23 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
   }
 
   /**
-   * Returns the available releases of Drupal core for a given updater.
+   * Returns the available releases of Drupal core for a given update stage.
    *
-   * @param \Drupal\automatic_updates\Updater $updater
-   *   The updater which will perform the update.
+   * @param \Drupal\automatic_updates\UpdateStage $stage
+   *   The update stage which will perform the update.
    *
    * @return \Drupal\update\ProjectRelease[]
    *   The available releases of Drupal core, keyed by version number and in
    *   descending order (i.e., newest first). Will be in ascending order (i.e.,
-   *   oldest first) if $updater is the cron updater.
+   *   oldest first) if $stage is the cron update stage.
    *
    * @see \Drupal\package_manager\ProjectInfo::getInstallableReleases()
    */
-  private function getAvailableReleases(Updater $updater): array {
+  private function getAvailableReleases(UpdateStage $stage): array {
     $project_info = new ProjectInfo('drupal');
     $available_releases = $project_info->getInstallableReleases() ?? [];
 
-    if ($updater instanceof CronUpdater) {
+    if ($stage instanceof CronUpdateStage) {
       $available_releases = array_reverse($available_releases);
     }
     return $available_releases;
diff --git a/src/Validator/XdebugValidator.php b/src/Validator/XdebugValidator.php
index 2994e18ab2f01e9a8f404967cd427c8e5ef4ad3b..030d71a5dcd738596ae21a3c73194097da33411b 100644
--- a/src/Validator/XdebugValidator.php
+++ b/src/Validator/XdebugValidator.php
@@ -6,7 +6,7 @@ namespace Drupal\automatic_updates\Validator;
 
 use Drupal\package_manager\Event\PreApplyEvent;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\package_manager\Event\PreCreateEvent;
 use Drupal\package_manager\Event\PreOperationStageEvent;
 use Drupal\package_manager\Event\StatusCheckEvent;
@@ -33,7 +33,7 @@ final class XdebugValidator extends PackageManagerXdebugValidator implements Eve
     $warning = $this->checkForXdebug();
 
     if ($warning) {
-      if ($stage instanceof CronUpdater) {
+      if ($stage instanceof CronUpdateStage) {
         // Cron updates are not allowed if Xdebug is enabled.
         $event->addError([$this->t("Xdebug is enabled, currently Cron Updates are not allowed while it is enabled. If Xdebug is not disabled you will not receive security and other updates during cron.")]);
       }
diff --git a/tests/modules/automatic_updates_test_api/src/ApiController.php b/tests/modules/automatic_updates_test_api/src/ApiController.php
index 352e49c4fa21ecf103ab274c55051e340170a86d..5790f3adebd0e684eda7e07e6520f65ba0da222d 100644
--- a/tests/modules/automatic_updates_test_api/src/ApiController.php
+++ b/tests/modules/automatic_updates_test_api/src/ApiController.php
@@ -20,7 +20,7 @@ class ApiController extends PackageManagerApiController {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('automatic_updates.updater'),
+      $container->get('automatic_updates.update_stage'),
       $container->get('package_manager.path_locator')
     );
   }
diff --git a/tests/modules/automatic_updates_test_cron/automatic_updates_test_cron.module b/tests/modules/automatic_updates_test_cron/automatic_updates_test_cron.module
index 87b6b10b9c4839ea0bf9121c53044f0c4952924b..2b7f3f485c26503d95258e950cdcf712934f718d 100644
--- a/tests/modules/automatic_updates_test_cron/automatic_updates_test_cron.module
+++ b/tests/modules/automatic_updates_test_cron/automatic_updates_test_cron.module
@@ -11,7 +11,7 @@
 declare(strict_types=1);
 
 use Drupal\package_manager\ProjectInfo;
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\Core\Extension\ExtensionVersion;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\update\ProjectSecurityData;
@@ -33,9 +33,9 @@ function automatic_updates_test_cron_form_update_settings_alter(array &$form, Fo
     '#type' => 'radios',
     '#title' => t('Automatically update Drupal core'),
     '#options' => [
-      CronUpdater::DISABLED => t('Disabled'),
-      CronUpdater::ALL => t('All supported updates'),
-      CronUpdater::SECURITY => t('Security updates only'),
+      CronUpdateStage::DISABLED => t('Disabled'),
+      CronUpdateStage::ALL => t('All supported updates'),
+      CronUpdateStage::SECURITY => t('Security updates only'),
     ],
     '#default_value' => \Drupal::config('automatic_updates.settings')->get('cron'),
     '#description' => t(
diff --git a/tests/src/Build/CoreUpdateTest.php b/tests/src/Build/CoreUpdateTest.php
index 2ce741fb58d1dd8fb6e95a63d4fdd00d84feda4c..db1a82f3c85df1877a5ffa1faea6177a7e7a5afc 100644
--- a/tests/src/Build/CoreUpdateTest.php
+++ b/tests/src/Build/CoreUpdateTest.php
@@ -5,8 +5,8 @@ declare(strict_types = 1);
 namespace Drupal\Tests\automatic_updates\Build;
 
 use Behat\Mink\Element\DocumentElement;
-use Drupal\automatic_updates\CronUpdater;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\CronUpdateStage;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\Composer\Composer;
 use Drupal\package_manager\Event\PostApplyEvent;
 use Drupal\package_manager\Event\PostCreateEvent;
@@ -113,7 +113,7 @@ class CoreUpdateTest extends UpdateTestBase {
     $update_status_code = $session->getStatusCode();
     $file_contents = $session->getPage()->getContent();
     $this->assertExpectedStageEventsFired(
-      Updater::class,
+      UpdateStage::class,
       [
         // ::assertReadOnlyFileSystemError attempts to start an update
         // multiple times so 'PreCreateEvent' will be fired multiple times.
@@ -157,7 +157,7 @@ class CoreUpdateTest extends UpdateTestBase {
     $assert_session->pageTextContains('Update complete!');
     $assert_session->pageTextContains('Up to date');
     $assert_session->pageTextNotContains('There is a security update available for your version of Drupal.');
-    $this->assertExpectedStageEventsFired(Updater::class);
+    $this->assertExpectedStageEventsFired(UpdateStage::class);
     $this->assertUpdateSuccessful('9.8.1');
   }
 
@@ -186,7 +186,7 @@ class CoreUpdateTest extends UpdateTestBase {
     $assert_session = $mink->assertSession();
     $page->clickLink('Run cron');
     $cron_run_status_code = $mink->getSession()->getStatusCode();
-    $this->assertExpectedStageEventsFired(CronUpdater::class);
+    $this->assertExpectedStageEventsFired(CronUpdateStage::class);
     $this->assertSame(200, $cron_run_status_code);
 
     // There should be log messages, but no errors or warnings should have been
diff --git a/tests/src/Functional/AutomaticUpdatesFunctionalTestBase.php b/tests/src/Functional/AutomaticUpdatesFunctionalTestBase.php
index 1636f8e86504e92b1fe4fb9b449127cc13d27096..f3285ceb215625fcfdd00aca2e13d7f2300d47ee 100644
--- a/tests/src/Functional/AutomaticUpdatesFunctionalTestBase.php
+++ b/tests/src/Functional/AutomaticUpdatesFunctionalTestBase.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Functional;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\fixture_manipulator\StageFixtureManipulator;
 use Drupal\package_manager\PathLocator;
 use Drupal\Tests\BrowserTestBase;
@@ -39,7 +39,7 @@ abstract class AutomaticUpdatesFunctionalTestBase extends BrowserTestBase {
     parent::setUp();
     $this->useFixtureDirectoryAsActive(__DIR__ . '/../../../package_manager/tests/fixtures/fake_site');
     // @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::SECURITY)->save();
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
   }
 
   /**
@@ -66,7 +66,7 @@ abstract class AutomaticUpdatesFunctionalTestBase extends BrowserTestBase {
     $service_ids = [
       // If automatic_updates is installed, ensure any stage directory created
       // during the test is cleaned up.
-      'automatic_updates.updater',
+      'automatic_updates.update_stage',
     ];
     foreach ($service_ids as $service_id) {
       if ($this->container->has($service_id)) {
diff --git a/tests/src/Functional/ErrorMessageOnStageDestroyTest.php b/tests/src/Functional/ErrorMessageOnStageDestroyTest.php
index 5a57e22f4836e3de42575705962dcd92170d518b..f3426ab4654b6da6be5eee65086861eb2334aaa4 100644
--- a/tests/src/Functional/ErrorMessageOnStageDestroyTest.php
+++ b/tests/src/Functional/ErrorMessageOnStageDestroyTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Functional;
 
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 
 /**
  * Tests error message when the stage the user is interacting with is destroyed.
@@ -54,11 +54,11 @@ class ErrorMessageOnStageDestroyTest extends AutomaticUpdatesFunctionalTestBase
     $page->pressButton('Update to 9.8.1');
     $this->checkForMetaRefresh();
     $this->assertUpdateReady('9.8.1');
-    $updater = $this->container->get(Updater::class);
+    $stage = $this->container->get(UpdateStage::class);
     $random_message = $this->randomString();
     // @see \Drupal\Tests\package_manager\Kernel\StageTest::testStoreDestroyInfo()
-    // @see \Drupal\automatic_updates\CronUpdater::performUpdate()
-    $updater->destroy(TRUE, t($random_message));
+    // @see \Drupal\automatic_updates\CronUpdateStage::performUpdate()
+    $stage->destroy(TRUE, t($random_message));
     $this->checkForMetaRefresh();
     $page->pressButton('Continue');
     $assert_session->pageTextContains($random_message);
diff --git a/tests/src/Functional/StatusCheckTest.php b/tests/src/Functional/StatusCheckTest.php
index be28a5fd5e86fd6de1db51bc1afaf58417f6844d..2c9a8fe0b1ea2c362734bc1e242eec7a6a2d4a90 100644
--- a/tests/src/Functional/StatusCheckTest.php
+++ b/tests/src/Functional/StatusCheckTest.php
@@ -5,7 +5,7 @@ declare(strict_types = 1);
 namespace Drupal\Tests\automatic_updates\Functional;
 
 use Behat\Mink\Element\NodeElement;
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates\StatusCheckMailer;
 use Drupal\automatic_updates_test\Datetime\TestTime;
 use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1;
@@ -381,7 +381,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
 
     // Confirm status check messages are not displayed when cron updates are
     // disabled.
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::DISABLED)->save();
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::DISABLED)->save();
     $this->drupalGet('admin/structure');
     $this->checkForMetaRefresh();
     $assert->pageTextNotContains(static::$warningsExplanation);
@@ -403,7 +403,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
     // the functionality to retrieve our fake release history metadata.
     $this->container->get('module_installer')->install(['automatic_updates', 'automatic_updates_test']);
     // @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::SECURITY)->save();
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
     $this->drupalGet('admin/reports/status');
     $this->assertNoErrors(TRUE);
 
diff --git a/tests/src/Kernel/AutomaticUpdatesKernelTestBase.php b/tests/src/Kernel/AutomaticUpdatesKernelTestBase.php
index 5a448f079b748a1966cb009b04007bc8ccceda31..d2afe3b9c803fad500c30c33d40258a4a7e380da 100644
--- a/tests/src/Kernel/AutomaticUpdatesKernelTestBase.php
+++ b/tests/src/Kernel/AutomaticUpdatesKernelTestBase.php
@@ -4,8 +4,8 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel;
 
-use Drupal\automatic_updates\CronUpdater;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\CronUpdateStage;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Url;
 use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
@@ -52,7 +52,7 @@ abstract class AutomaticUpdatesKernelTestBase extends PackageManagerKernelTestBa
     parent::setUp();
     // Enable cron updates, which will eventually be the default.
     // @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::SECURITY)->save();
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
 
     // By default, pretend we're running Drupal core 9.8.0 and a non-security
     // update to 9.8.1 is available.
@@ -71,10 +71,10 @@ abstract class AutomaticUpdatesKernelTestBase extends PackageManagerKernelTestBa
   public function register(ContainerBuilder $container) {
     parent::register($container);
 
-    // Use the test-only implementations of the regular and cron updaters.
+    // Use the test-only implementations of the regular and cron update stages.
     $overrides = [
-      'automatic_updates.updater' => TestUpdater::class,
-      'automatic_updates.cron_updater' => TestCronUpdater::class,
+      'automatic_updates.update_stage' => TestUpdateStage::class,
+      'automatic_updates.cron_update_stage' => TestCronUpdateStage::class,
     ];
     foreach ($overrides as $service_id => $class) {
       if ($container->hasDefinition($service_id)) {
@@ -86,9 +86,9 @@ abstract class AutomaticUpdatesKernelTestBase extends PackageManagerKernelTestBa
 }
 
 /**
- * A test-only version of the regular updater to override internals.
+ * A test-only version of the regular update stage to override internals.
  */
-class TestUpdater extends Updater {
+class TestUpdateStage extends UpdateStage {
 
   /**
    * {@inheritdoc}
@@ -100,9 +100,9 @@ class TestUpdater extends Updater {
 }
 
 /**
- * A test-only version of the cron updater to override and expose internals.
+ * A test-only version of the cron update stage to override and expose internals.
  */
-class TestCronUpdater extends CronUpdater {
+class TestCronUpdateStage extends CronUpdateStage {
 
   /**
    * {@inheritdoc}
diff --git a/tests/src/Kernel/CronUpdaterTest.php b/tests/src/Kernel/CronUpdateStageTest.php
similarity index 89%
rename from tests/src/Kernel/CronUpdaterTest.php
rename to tests/src/Kernel/CronUpdateStageTest.php
index b941eb707c4e61ab78507fd5122d134b848090e1..cfc4f09ae490e8909471c8d606730d2833b606f4 100644
--- a/tests/src/Kernel/CronUpdaterTest.php
+++ b/tests/src/Kernel/CronUpdateStageTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Logger\RfcLogLevel;
@@ -30,12 +30,12 @@ use ColinODell\PsrTestLogger\TestLogger;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
- * @covers \Drupal\automatic_updates\CronUpdater
+ * @covers \Drupal\automatic_updates\CronUpdateStage
  * @covers \automatic_updates_test_cron_form_update_settings_alter
  * @group automatic_updates
  * @internal
  */
-class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
+class CronUpdateStageTest extends AutomaticUpdatesKernelTestBase {
 
   use EmailNotificationsTestTrait;
   use PackageManagerBypassTestTrait;
@@ -87,42 +87,42 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
   }
 
   /**
-   * Data provider for testUpdaterCalled().
+   * Data provider for testUpdateStageCalled().
    *
    * @return mixed[][]
    *   The test cases.
    */
-  public function providerUpdaterCalled(): array {
+  public function providerUpdateStageCalled(): array {
     $fixture_dir = __DIR__ . '/../../../package_manager/tests/fixtures/release-history';
 
     return [
       'disabled, normal release' => [
-        CronUpdater::DISABLED,
+        CronUpdateStage::DISABLED,
         ['drupal' => "$fixture_dir/drupal.9.8.2.xml"],
         FALSE,
       ],
       'disabled, security release' => [
-        CronUpdater::DISABLED,
+        CronUpdateStage::DISABLED,
         ['drupal' => "$fixture_dir/drupal.9.8.1-security.xml"],
         FALSE,
       ],
       'security only, security release' => [
-        CronUpdater::SECURITY,
+        CronUpdateStage::SECURITY,
         ['drupal' => "$fixture_dir/drupal.9.8.1-security.xml"],
         TRUE,
       ],
       'security only, normal release' => [
-        CronUpdater::SECURITY,
+        CronUpdateStage::SECURITY,
         ['drupal' => "$fixture_dir/drupal.9.8.2.xml"],
         FALSE,
       ],
       'enabled, normal release' => [
-        CronUpdater::ALL,
+        CronUpdateStage::ALL,
         ['drupal' => "$fixture_dir/drupal.9.8.2.xml"],
         TRUE,
       ],
       'enabled, security release' => [
-        CronUpdater::ALL,
+        CronUpdateStage::ALL,
         ['drupal' => "$fixture_dir/drupal.9.8.1-security.xml"],
         TRUE,
       ],
@@ -130,7 +130,7 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
   }
 
   /**
-   * Tests that the cron handler calls the updater as expected.
+   * Tests that the cron handler calls the update stage as expected.
    *
    * @param string $setting
    *   Whether automatic updates should be enabled during cron. Possible values
@@ -142,9 +142,9 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
    * @param bool $will_update
    *   Whether an update should be performed, given the previous two arguments.
    *
-   * @dataProvider providerUpdaterCalled
+   * @dataProvider providerUpdateStageCalled
    */
-  public function testUpdaterCalled(string $setting, array $release_data, bool $will_update): void {
+  public function testUpdateStageCalled(string $setting, array $release_data, bool $will_update): void {
     $version = strpos($release_data['drupal'], '9.8.2') ? '9.8.2' : '9.8.1';
     if ($will_update) {
       $this->getStageFixtureManipulator()->setCorePackageVersion($version);
@@ -258,22 +258,22 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
     }
     $this->installConfig('automatic_updates');
     // @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::SECURITY)->save();
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
     // Ensure that there is a security release to which we should update.
     $this->setReleaseMetadata([
       'drupal' => __DIR__ . "/../../../package_manager/tests/fixtures/release-history/drupal.9.8.1-security.xml",
     ]);
 
     // If the pre- or post-destroy events throw an exception, it will not be
-    // caught by the cron updater, but it *will* be caught by the main cron
+    // caught by the cron update stage, but it *will* be caught by the main cron
     // service, which will log it as a cron error that we'll want to check for.
     $cron_logger = new TestLogger();
     $this->container->get('logger.factory')
       ->get('cron')
       ->addLogger($cron_logger);
 
-    /** @var \Drupal\automatic_updates\CronUpdater $updater */
-    $updater = $this->container->get(CronUpdater::class);
+    /** @var \Drupal\automatic_updates\CronUpdateStage $stage */
+    $stage = $this->container->get(CronUpdateStage::class);
 
     // When the event specified by $event_class is dispatched, either throw an
     // exception directly from the event subscriber, or prepare a
@@ -282,7 +282,7 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
       $error = ValidationResult::createError([
         t('Destroy the stage!'),
       ]);
-      $exception = $this->createStageEventExceptionFromResults([$error], $event_class, $updater);
+      $exception = $this->createStageEventExceptionFromResults([$error], $event_class, $stage);
       TestSubscriber1::setTestResult($exception->event->getResults(), $event_class);
     }
     else {
@@ -296,10 +296,10 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
     $this->assertEmpty($cron_logger->records);
     $this->assertEmpty($this->logger->records);
 
-    $this->assertTrue($updater->isAvailable());
+    $this->assertTrue($stage->isAvailable());
     $this->container->get('cron')->run();
 
-    $logged_by_updater = $this->logger->hasRecord($expected_log_message, (string) RfcLogLevel::ERROR);
+    $logged_by_stage = $this->logger->hasRecord($expected_log_message, (string) RfcLogLevel::ERROR);
     // To check if the exception was logged by the main cron service, we need
     // to set up a special predicate, because exceptions logged by cron are
     // always formatted in a particular way that we don't control. But the
@@ -315,20 +315,20 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
     $logged_by_cron = $cron_logger->hasRecordThatPasses($predicate, (string) RfcLogLevel::ERROR);
 
     // If a pre-destroy event flags a validation error, it's handled like any
-    // other event (logged by the cron updater, but not the main cron service).
-    // But if a pre- or post-destroy event throws an exception, the cron updater
-    // won't try to catch it. Instead, it will be caught and logged by the main
-    // cron service.
+    // other event (logged by the cron update stage, but not the main cron
+    // service). But if a pre- or post-destroy event throws an exception, the
+    // cron update stage won't try to catch it. Instead, it will be caught and
+    // logged by the main cron service.
     if ($event_class === PreDestroyEvent::class || $event_class === PostDestroyEvent::class) {
       // If the pre-destroy event throws an exception or flags a validation
       // error, the stage won't be destroyed. But, once the post-destroy event
       // is fired, the stage should be fully destroyed and marked as available.
-      $this->assertSame($event_class === PostDestroyEvent::class, $updater->isAvailable());
+      $this->assertSame($event_class === PostDestroyEvent::class, $stage->isAvailable());
     }
     else {
-      $this->assertTrue($updater->isAvailable());
+      $this->assertTrue($stage->isAvailable());
     }
-    $this->assertTrue($logged_by_updater);
+    $this->assertTrue($logged_by_stage);
     $this->assertFalse($logged_by_cron);
   }
 
@@ -366,7 +366,7 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
    * Tests stage is not destroyed if another update is applying.
    */
   public function testStageNotDestroyedIfApplying(): void {
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::ALL)->save();
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::ALL)->save();
     $this->setReleaseMetadata([
       'drupal' => __DIR__ . "/../../../package_manager/tests/fixtures/release-history/drupal.9.8.1-security.xml",
     ]);
@@ -380,7 +380,7 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
     // another stage is applying.
     $this->addEventTestListener(function (PreApplyEvent $event) use ($stop_error) {
       // Ensure the stage that is applying the operation is not the cron
-      // updater.
+      // update stage.
       $this->assertInstanceOf(TestStage::class, $event->stage);
       $this->container->get('cron')->run();
       // We do not actually want to apply this operation it was just invoked to
@@ -404,7 +404,7 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
    * Tests stage is not destroyed if not available and site is on secure version.
    */
   public function testStageNotDestroyedIfSecure(): void {
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::ALL)->save();
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::ALL)->save();
     $this->setReleaseMetadata([
       'drupal' => __DIR__ . "/../../../package_manager/tests/fixtures/release-history/drupal.9.8.2.xml",
     ]);
@@ -414,8 +414,8 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
     $stage->require(['drupal/random']);
     $this->assertUpdateStagedTimes(1);
 
-    // Trigger CronUpdater, the above should cause it to detect a stage that is
-    // applying.
+    // Trigger CronUpdateStage, the above should cause it to detect a stage that
+    // is applying.
     $this->container->get('cron')->run();
 
     $this->assertTrue($this->logger->hasRecord('Cron will not perform any updates because there is an existing stage and the current version of the site is secure.', (string) RfcLogLevel::NOTICE));
@@ -423,11 +423,11 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
   }
 
   /**
-   * Tests that CronUpdater::begin() unconditionally throws an exception.
+   * Tests that CronUpdateStage::begin() unconditionally throws an exception.
    */
   public function testBeginThrowsException(): void {
-    $this->expectExceptionMessage(CronUpdater::class . '::begin() cannot be called directly.');
-    $this->container->get(CronUpdater::class)
+    $this->expectExceptionMessage(CronUpdateStage::class . '::begin() cannot be called directly.');
+    $this->container->get(CronUpdateStage::class)
       ->begin(['drupal' => '9.8.1']);
   }
 
@@ -489,13 +489,13 @@ END;
       'drupal' => __DIR__ . '/../../../package_manager/tests/fixtures/release-history/drupal.9.8.2.xml',
     ]);
     $this->config('automatic_updates.settings')
-      ->set('cron', CronUpdater::ALL)
+      ->set('cron', CronUpdateStage::ALL)
       ->save();
 
     $error = ValidationResult::createError([
       t('Error while updating!'),
     ]);
-    $exception = $this->createStageEventExceptionFromResults([$error], $event_class, $this->container->get(CronUpdater::class));
+    $exception = $this->createStageEventExceptionFromResults([$error], $event_class, $this->container->get(CronUpdateStage::class));
     TestSubscriber1::setTestResult($exception->event->getResults(), $event_class);
 
     $this->container->get('cron')->run();
@@ -537,7 +537,7 @@ END;
       t('Error while updating!'),
     ]);
     TestSubscriber1::setTestResult([$error], $event_class);
-    $exception = $this->createStageEventExceptionFromResults([$error], $event_class, $this->container->get(CronUpdater::class));
+    $exception = $this->createStageEventExceptionFromResults([$error], $event_class, $this->container->get(CronUpdateStage::class));
 
     $this->container->get('cron')->run();
 
@@ -581,11 +581,11 @@ END;
   }
 
   /**
-   * Tests that setLogger is called on the cron updater service.
+   * Tests that setLogger is called on the cron update stage service.
    */
   public function testLoggerIsSetByContainer(): void {
-    $updater_method_calls = $this->container->getDefinition('automatic_updates.cron_updater')->getMethodCalls();
-    $this->assertSame('setLogger', $updater_method_calls[0][0]);
+    $stage_method_calls = $this->container->getDefinition('automatic_updates.cron_update_stage')->getMethodCalls();
+    $this->assertSame('setLogger', $stage_method_calls[0][0]);
   }
 
 }
diff --git a/tests/src/Kernel/ReleaseChooserTest.php b/tests/src/Kernel/ReleaseChooserTest.php
index d8d6d4ee7dae7391f64bc66c48daf4fa5a5e73fa..c354980813158c07e1b4a895e67c5646e7a183ad 100644
--- a/tests/src/Kernel/ReleaseChooserTest.php
+++ b/tests/src/Kernel/ReleaseChooserTest.php
@@ -4,9 +4,9 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates\ReleaseChooser;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\Core\Extension\ExtensionVersion;
 use Drupal\update\ProjectRelease;
 
@@ -41,84 +41,84 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
   public function providerReleases(): array {
     return [
       'installed 9.8.0, no minor support' => [
-        'updater' => Updater::class,
+        'stage' => UpdateStage::class,
         'minor_support' => FALSE,
         'installed_version' => '9.8.0',
         'current_minor' => '9.8.2',
         'next_minor' => NULL,
       ],
       'installed 9.8.0, minor support' => [
-        'updater' => Updater::class,
+        'stage' => UpdateStage::class,
         'minor_support' => TRUE,
         'installed_version' => '9.8.0',
         'current_minor' => '9.8.2',
         'next_minor' => NULL,
       ],
       'installed 9.7.0, no minor support' => [
-        'updater' => Updater::class,
+        'stage' => UpdateStage::class,
         'minor_support' => FALSE,
         'installed_version' => '9.7.0',
         'current_minor' => '9.7.1',
         'next_minor' => NULL,
       ],
       'installed 9.7.0, minor support' => [
-        'updater' => Updater::class,
+        'stage' => UpdateStage::class,
         'minor_support' => TRUE,
         'installed_version' => '9.7.0',
         'current_minor' => '9.7.1',
         'next_minor' => '9.8.2',
       ],
       'installed 9.7.2, no minor support' => [
-        'updater' => Updater::class,
+        'stage' => UpdateStage::class,
         'minor_support' => FALSE,
         'installed_version' => '9.7.2',
         'current_minor' => NULL,
         'next_minor' => NULL,
       ],
       'installed 9.7.2, minor support' => [
-        'updater' => Updater::class,
+        'stage' => UpdateStage::class,
         'minor_support' => TRUE,
         'installed_version' => '9.7.2',
         'current_minor' => NULL,
         'next_minor' => '9.8.2',
       ],
       'cron, installed 9.8.0, no minor support' => [
-        'updater' => CronUpdater::class,
+        'stage' => CronUpdateStage::class,
         'minor_support' => FALSE,
         'installed_version' => '9.8.0',
         'current_minor' => '9.8.1',
         'next_minor' => NULL,
       ],
       'cron, installed 9.8.0, minor support' => [
-        'updater' => CronUpdater::class,
+        'stage' => CronUpdateStage::class,
         'minor_support' => TRUE,
         'installed_version' => '9.8.0',
         'current_minor' => '9.8.1',
         'next_minor' => NULL,
       ],
       'cron, installed 9.7.0, no minor support' => [
-        'updater' => CronUpdater::class,
+        'stage' => CronUpdateStage::class,
         'minor_support' => FALSE,
         'installed_version' => '9.7.0',
         'current_minor' => '9.7.1',
         'next_minor' => NULL,
       ],
       'cron, installed 9.7.0, minor support' => [
-        'updater' => CronUpdater::class,
+        'stage' => CronUpdateStage::class,
         'minor_support' => TRUE,
         'installed_version' => '9.7.0',
         'current_minor' => '9.7.1',
         'next_minor' => NULL,
       ],
       'cron, installed 9.7.2, no minor support' => [
-        'updater' => CronUpdater::class,
+        'stage' => CronUpdateStage::class,
         'minor_support' => FALSE,
         'installed_version' => '9.7.2',
         'current_minor' => NULL,
         'next_minor' => NULL,
       ],
       'cron, installed 9.7.2, minor support' => [
-        'updater' => CronUpdater::class,
+        'stage' => CronUpdateStage::class,
         'minor_support' => TRUE,
         'installed_version' => '9.7.2',
         'current_minor' => NULL,
@@ -130,8 +130,8 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
   /**
    * Tests fetching the recommended release when an update is available.
    *
-   * @param string $updater_service
-   *   The ID of the updater service to use.
+   * @param string $stage_service
+   *   The ID of the update stage service to use.
    * @param bool $minor_support
    *   Whether updates to the next minor will be allowed.
    * @param string $installed_version
@@ -148,21 +148,21 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
    * @covers ::getLatestInNextMinor
    * @covers ::getMostRecentReleaseInMinor
    */
-  public function testReleases(string $updater_service, bool $minor_support, string $installed_version, ?string $current_minor, ?string $next_minor): void {
+  public function testReleases(string $stage_service, bool $minor_support, string $installed_version, ?string $current_minor, ?string $next_minor): void {
     $this->setCoreVersion($installed_version);
     $this->config('automatic_updates.settings')->set('allow_core_minor_updates', $minor_support)->save();
     $chooser = $this->container->get(ReleaseChooser::class);
-    $updater = $this->container->get($updater_service);
-    $this->assertReleaseVersion($current_minor, $chooser->getLatestInInstalledMinor($updater));
-    $this->assertReleaseVersion($next_minor, $chooser->getLatestInNextMinor($updater));
+    $stage = $this->container->get($stage_service);
+    $this->assertReleaseVersion($current_minor, $chooser->getLatestInInstalledMinor($stage));
+    $this->assertReleaseVersion($next_minor, $chooser->getLatestInNextMinor($stage));
 
-    $this->assertReleaseVersion($current_minor, $chooser->getMostRecentReleaseInMinor($updater, $this->getRelativeVersion($installed_version, 0)));
+    $this->assertReleaseVersion($current_minor, $chooser->getMostRecentReleaseInMinor($stage, $this->getRelativeVersion($installed_version, 0)));
     $next_minor_version = $this->getRelativeVersion($installed_version, 1);
-    $this->assertReleaseVersion($next_minor, $chooser->getMostRecentReleaseInMinor($updater, $next_minor_version));
+    $this->assertReleaseVersion($next_minor, $chooser->getMostRecentReleaseInMinor($stage, $next_minor_version));
     $previous_minor_version = $this->getRelativeVersion($installed_version, -1);
     // The chooser should never return a release for a minor before the
     // currently installed version.
-    $this->assertReleaseVersion(NULL, $chooser->getMostRecentReleaseInMinor($updater, $previous_minor_version));
+    $this->assertReleaseVersion(NULL, $chooser->getMostRecentReleaseInMinor($stage, $previous_minor_version));
   }
 
   /**
diff --git a/tests/src/Kernel/StatusCheck/CronFrequencyValidatorTest.php b/tests/src/Kernel/StatusCheck/CronFrequencyValidatorTest.php
index cf3c459c84c18994ed97ea3b589f22ae22f6ef2c..c601479274f145a95286ee6f4127ec72a3fd6c22 100644
--- a/tests/src/Kernel/StatusCheck/CronFrequencyValidatorTest.php
+++ b/tests/src/Kernel/StatusCheck/CronFrequencyValidatorTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates\Validator\CronFrequencyValidator;
 use Drupal\package_manager\ValidationResult;
 use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase;
@@ -41,7 +41,7 @@ class CronFrequencyValidatorTest extends AutomaticUpdatesKernelTestBase {
    */
   public function testNoValidationIfCronDisabled(): void {
     $this->config('automatic_updates.settings')
-      ->set('cron', CronUpdater::DISABLED)
+      ->set('cron', CronUpdateStage::DISABLED)
       ->save();
 
     $validator = new class (
@@ -49,7 +49,6 @@ class CronFrequencyValidatorTest extends AutomaticUpdatesKernelTestBase {
       $this->container->get('module_handler'),
       $this->container->get('state'),
       $this->container->get('datetime.time'),
-      $this->container->get(CronUpdater::class),
       $this->container->get('lock')
     ) extends CronFrequencyValidator {
 
diff --git a/tests/src/Kernel/StatusCheck/CronServerValidatorTest.php b/tests/src/Kernel/StatusCheck/CronServerValidatorTest.php
index 122c8e08b98a4e9361c1c92667fd2ae0c21313bb..0c036ee256eeb87f0655b7f2ebd6ae17bde7503a 100644
--- a/tests/src/Kernel/StatusCheck/CronServerValidatorTest.php
+++ b/tests/src/Kernel/StatusCheck/CronServerValidatorTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates\Validator\CronServerValidator;
 use Drupal\Core\Logger\RfcLogLevel;
 use Drupal\Core\Url;
@@ -39,7 +39,7 @@ class CronServerValidatorTest extends AutomaticUpdatesKernelTestBase {
     ]);
     // Add all the test cases where there no expected results for all cron
     // modes.
-    foreach ([CronUpdater::DISABLED, CronUpdater::SECURITY, CronUpdater::ALL] as $cron_mode) {
+    foreach ([CronUpdateStage::DISABLED, CronUpdateStage::SECURITY, CronUpdateStage::ALL] as $cron_mode) {
       $test_cases["PHP server with alternate port, cron $cron_mode"] = [
         TRUE,
         'cli-server',
@@ -61,7 +61,7 @@ class CronServerValidatorTest extends AutomaticUpdatesKernelTestBase {
     }
     // If the PHP server is used with the same port and cron is enabled an error
     // will be flagged.
-    foreach ([CronUpdater::SECURITY, CronUpdater::ALL] as $cron_mode) {
+    foreach ([CronUpdateStage::SECURITY, CronUpdateStage::ALL] as $cron_mode) {
       $test_cases["PHP server with same port, cron $cron_mode"] = [
         FALSE,
         'cli-server',
@@ -72,7 +72,7 @@ class CronServerValidatorTest extends AutomaticUpdatesKernelTestBase {
     $test_cases["PHP server with same port, cron disabled"] = [
       FALSE,
       'cli-server',
-      CronUpdater::DISABLED,
+      CronUpdateStage::DISABLED,
       [],
     ];
     return $test_cases;
@@ -87,19 +87,19 @@ class CronServerValidatorTest extends AutomaticUpdatesKernelTestBase {
    *   The value of the PHP_SAPI constant, as known to the validator.
    * @param string $cron_mode
    *   The cron mode to test with. Can be any of
-   *   \Drupal\automatic_updates\CronUpdater::DISABLED,
-   *   \Drupal\automatic_updates\CronUpdater::SECURITY, or
-   *   \Drupal\automatic_updates\CronUpdater::ALL.
+   *   \Drupal\automatic_updates\CronUpdateStage::DISABLED,
+   *   \Drupal\automatic_updates\CronUpdateStage::SECURITY, or
+   *   \Drupal\automatic_updates\CronUpdateStage::ALL.
    * @param \Drupal\package_manager\ValidationResult[] $expected_results
    *   The expected validation results.
    *
    * @dataProvider providerCronServerValidation
    */
   public function testCronServerValidationDuringPreCreate(bool $alternate_port, string $server_api, string $cron_mode, array $expected_results): void {
-    // If CronUpdater is disabled, a stage will never be created; nor will it if
-    // validation results happen before the stage is even created: in either
-    // case the stage fixture need not be manipulated.
-    if ($cron_mode !== CronUpdater::DISABLED && empty($expected_results)) {
+    // If CronUpdateStage is disabled, a stage will never be created; nor will
+    // it if validation results happen before the stage is even created: in
+    // either case the stage fixture need not be manipulated.
+    if ($cron_mode !== CronUpdateStage::DISABLED && empty($expected_results)) {
       $this->getStageFixtureManipulator()->setCorePackageVersion('9.8.1');
     }
     $request = $this->container->get('request_stack')->getCurrentRequest();
@@ -145,18 +145,18 @@ class CronServerValidatorTest extends AutomaticUpdatesKernelTestBase {
    *   The value of the PHP_SAPI constant, as known to the validator.
    * @param string $cron_mode
    *   The cron mode to test with. Can be any of
-   *   \Drupal\automatic_updates\CronUpdater::DISABLED,
-   *   \Drupal\automatic_updates\CronUpdater::SECURITY, or
-   *   \Drupal\automatic_updates\CronUpdater::ALL.
+   *   \Drupal\automatic_updates\CronUpdateStage::DISABLED,
+   *   \Drupal\automatic_updates\CronUpdateStage::SECURITY, or
+   *   \Drupal\automatic_updates\CronUpdateStage::ALL.
    * @param \Drupal\package_manager\ValidationResult[] $expected_results
    *   The expected validation results.
    *
    * @dataProvider providerCronServerValidation
    */
   public function testCronServerValidationDuringPreApply(bool $alternate_port, string $server_api, string $cron_mode, array $expected_results): void {
-    // If CronUpdater is disabled, a stage will never be created, hence
+    // If CronUpdateStage is disabled, a stage will never be created, hence
     // stage fixture need not be manipulated.
-    if ($cron_mode !== CronUpdater::DISABLED) {
+    if ($cron_mode !== CronUpdateStage::DISABLED) {
       $this->getStageFixtureManipulator()->setCorePackageVersion('9.8.1');
     }
     $request = $this->container->get('request_stack')->getCurrentRequest();
@@ -206,9 +206,9 @@ class CronServerValidatorTest extends AutomaticUpdatesKernelTestBase {
    *   The value of the PHP_SAPI constant, as known to the validator.
    * @param string $cron_mode
    *   The cron mode to test with. Can contain be of
-   *   \Drupal\automatic_updates\CronUpdater::DISABLED,
-   *   \Drupal\automatic_updates\CronUpdater::SECURITY, or
-   *   \Drupal\automatic_updates\CronUpdater::ALL.
+   *   \Drupal\automatic_updates\CronUpdateStage::DISABLED,
+   *   \Drupal\automatic_updates\CronUpdateStage::SECURITY, or
+   *   \Drupal\automatic_updates\CronUpdateStage::ALL.
    * @param \Drupal\package_manager\ValidationResult[] $expected_results
    *   The expected validation results.
    *
diff --git a/tests/src/Kernel/StatusCheck/RequestedUpdateValidatorTest.php b/tests/src/Kernel/StatusCheck/RequestedUpdateValidatorTest.php
index c412f4c92ddfa052b5953cd9f5e7d0b7e41c3963..623282199310e668bc3b2735459e7fae2f6ce4cb 100644
--- a/tests/src/Kernel/StatusCheck/RequestedUpdateValidatorTest.php
+++ b/tests/src/Kernel/StatusCheck/RequestedUpdateValidatorTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\package_manager\Exception\StageEventException;
 use Drupal\package_manager\ValidationResult;
 use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase;
@@ -31,7 +31,7 @@ class RequestedUpdateValidatorTest extends AutomaticUpdatesKernelTestBase {
     // Update `drupal/core-recommended` to a version that does not match the
     // requested version of '9.8.1'. This also does not update all packages that
     // are expected to be updated when updating Drupal core.
-    // @see \Drupal\automatic_updates\Updater::begin()
+    // @see \Drupal\automatic_updates\UpdateStage::begin()
     // @see \Drupal\package_manager\InstalledPackagesList::getCorePackages()
     $this->getStageFixtureManipulator()->setVersion('drupal/core-recommended', '9.8.2');
     $this->setCoreVersion('9.8.0');
@@ -40,16 +40,16 @@ class RequestedUpdateValidatorTest extends AutomaticUpdatesKernelTestBase {
     ]);
     $this->container->get('module_installer')->install(['automatic_updates']);
 
-    $updater = $this->container->get(Updater::class);
-    $updater->begin(['drupal' => '9.8.1']);
-    $updater->stage();
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin(['drupal' => '9.8.1']);
+    $stage->stage();
 
     $expected_results = [
       ValidationResult::createError([t("The requested update to 'drupal/core-recommended' to version '9.8.1' does not match the actual staged update to '9.8.2'.")]),
       ValidationResult::createError([t("The requested update to 'drupal/core-dev' to version '9.8.1' was not performed.")]),
     ];
     try {
-      $updater->apply();
+      $stage->apply();
       $this->fail('Expecting an exception.');
     }
     catch (StageEventException $exception) {
@@ -72,12 +72,12 @@ class RequestedUpdateValidatorTest extends AutomaticUpdatesKernelTestBase {
     ]);
     $this->container->get('module_installer')->install(['automatic_updates']);
 
-    $updater = $this->container->get(Updater::class);
-    $updater->begin(['drupal' => '9.8.1']);
-    $updater->stage();
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin(['drupal' => '9.8.1']);
+    $stage->stage();
     $this->expectException(StageEventException::class);
     $this->expectExceptionMessage('No updates detected in the staging area.');
-    $updater->apply();
+    $stage->apply();
   }
 
 }
diff --git a/tests/src/Kernel/StatusCheck/ScaffoldFilePermissionsValidatorTest.php b/tests/src/Kernel/StatusCheck/ScaffoldFilePermissionsValidatorTest.php
index 7e524e077db4baae06f304fdaddd3e0be5e60cd4..c7d9d2389fefd631cd3a558502f7c93a071e4a89 100644
--- a/tests/src/Kernel/StatusCheck/ScaffoldFilePermissionsValidatorTest.php
+++ b/tests/src/Kernel/StatusCheck/ScaffoldFilePermissionsValidatorTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\fixture_manipulator\ActiveFixtureManipulator;
 use Drupal\package_manager\Exception\ApplyFailedException;
 use Drupal\package_manager\Exception\StageEventException;
@@ -122,7 +122,7 @@ class ScaffoldFilePermissionsValidatorTest extends AutomaticUpdatesKernelTestBas
     $this->assertCheckerResultsFromManager($expected_results, TRUE);
 
     try {
-      $this->container->get(Updater::class)
+      $this->container->get(UpdateStage::class)
         ->begin(['drupal' => '9.8.1']);
 
       // If no exception was thrown, ensure that we weren't expecting an error.
@@ -330,14 +330,14 @@ class ScaffoldFilePermissionsValidatorTest extends AutomaticUpdatesKernelTestBas
     touch($this->activeDir . '/sites/default/deleted.txt');
     touch($this->activeDir . '/foo.txt');
 
-    $updater = $this->container->get(Updater::class);
-    $updater->begin(['drupal' => '9.8.1']);
-    $updater->stage();
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin(['drupal' => '9.8.1']);
+    $stage->stage();
 
     $this->writeProtect($write_protected_paths);
 
     try {
-      $updater->apply();
+      $stage->apply();
 
       // If no exception was thrown, ensure that we weren't expecting an error.
       $this->assertSame([], $expected_results);
diff --git a/tests/src/Kernel/StatusCheck/StagedDatabaseUpdateValidatorTest.php b/tests/src/Kernel/StatusCheck/StagedDatabaseUpdateValidatorTest.php
index 2bffc504a9059b528e5aaa7d476a47d757ec17f4..7ca9e175cc967188d00e919f45d98e5cc00cf155 100644
--- a/tests/src/Kernel/StatusCheck/StagedDatabaseUpdateValidatorTest.php
+++ b/tests/src/Kernel/StatusCheck/StagedDatabaseUpdateValidatorTest.php
@@ -42,7 +42,7 @@ class StagedDatabaseUpdateValidatorTest extends AutomaticUpdatesKernelTestBase {
   ];
 
   /**
-   * The test logger to collected messages logged by the cron updater.
+   * The test logger to collected messages logged by the cron update stage.
    *
    * @var \Psr\Log\Test\TestLogger
    */
diff --git a/tests/src/Kernel/StatusCheck/StagedProjectsValidatorTest.php b/tests/src/Kernel/StatusCheck/StagedProjectsValidatorTest.php
index d422e360d18e370e1ac6b8b236dfa92784f32050..0985e5c400e6e51a1c51ef38529f256d65062ab8 100644
--- a/tests/src/Kernel/StatusCheck/StagedProjectsValidatorTest.php
+++ b/tests/src/Kernel/StatusCheck/StagedProjectsValidatorTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\fixture_manipulator\ActiveFixtureManipulator;
 use Drupal\package_manager\Exception\StageEventException;
 use Drupal\package_manager\ValidationResult;
@@ -105,11 +105,11 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase {
     ];
     $error = ValidationResult::createError($messages, t('The update cannot proceed because the following Drupal projects were installed during the update.'));
 
-    $updater = $this->container->get(Updater::class);
-    $updater->begin(['drupal' => '9.8.1']);
-    $updater->stage();
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin(['drupal' => '9.8.1']);
+    $stage->stage();
     try {
-      $updater->apply();
+      $stage->apply();
       $this->fail('Expected an error, but none was raised.');
     }
     catch (StageEventException $e) {
@@ -177,11 +177,11 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase {
       t("theme 'drupal/test_theme' removed."),
     ];
     $error = ValidationResult::createError($messages, t('The update cannot proceed because the following Drupal projects were removed during the update.'));
-    $updater = $this->container->get(Updater::class);
-    $updater->begin(['drupal' => '9.8.1']);
-    $updater->stage();
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin(['drupal' => '9.8.1']);
+    $stage->stage();
     try {
-      $updater->apply();
+      $stage->apply();
       $this->fail('Expected an error, but none was raised.');
     }
     catch (StageEventException $e) {
@@ -236,12 +236,12 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase {
       t("module 'drupal/test-module' from 1.3.0 to 1.3.1."),
     ];
     $error = ValidationResult::createError($messages, t('The update cannot proceed because the following Drupal projects were unexpectedly updated. Only Drupal Core updates are currently supported.'));
-    $updater = $this->container->get(Updater::class);
-    $updater->begin(['drupal' => '9.8.1']);
-    $updater->stage();
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin(['drupal' => '9.8.1']);
+    $stage->stage();
 
     try {
-      $updater->apply();
+      $stage->apply();
       $this->fail('Expected an error, but none was raised.');
     }
     catch (StageEventException $e) {
@@ -317,10 +317,10 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase {
       ->removePackage('other/removed')
       ->removePackage('other/dev-removed', TRUE);
 
-    $updater = $this->container->get(Updater::class);
-    $updater->begin(['drupal' => '9.8.1']);
-    $updater->stage();
-    $updater->apply();
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin(['drupal' => '9.8.1']);
+    $stage->stage();
+    $stage->apply();
     $this->assertTrue(TRUE);
   }
 
diff --git a/tests/src/Kernel/StatusCheck/StatusCheckFailureEmailTest.php b/tests/src/Kernel/StatusCheck/StatusCheckFailureEmailTest.php
index 61e631f7ffd09dad4d417d356513462634f183ac..4b143af32dc61b59d0e755e9dc52ab7eaeaeb3b7 100644
--- a/tests/src/Kernel/StatusCheck/StatusCheckFailureEmailTest.php
+++ b/tests/src/Kernel/StatusCheck/StatusCheckFailureEmailTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates\StatusCheckMailer;
 use Drupal\automatic_updates_test\Datetime\TestTime;
 use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1;
@@ -54,7 +54,7 @@ class StatusCheckFailureEmailTest extends AutomaticUpdatesKernelTestBase {
 
     $this->installConfig('automatic_updates');
     // @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::SECURITY)->save();
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
     $this->setUpEmailRecipients();
 
     // Allow stored available update data to live for a very, very long time.
@@ -212,7 +212,7 @@ END;
 
     // If we disable unattended updates entirely and flag a new error, they
     // should not be e-mailed.
-    $config->set('cron', CronUpdater::DISABLED)->save();
+    $config->set('cron', CronUpdateStage::DISABLED)->save();
     $error = $this->createValidationResult(SystemManager::REQUIREMENT_ERROR);
     TestSubscriber1::setTestResult([$error], StatusCheckEvent::class);
     $this->runCron();
@@ -220,7 +220,7 @@ END;
 
     // If we re-enable unattended updates, they should be emailed again, even if
     // the results haven't changed.
-    $config->set('cron', CronUpdater::ALL)->save();
+    $config->set('cron', CronUpdateStage::ALL)->save();
     $this->runCron();
     $sent_messages_count += $recipient_count;
     $this->assertSentMessagesCount($sent_messages_count);
diff --git a/tests/src/Kernel/StatusCheck/StatusCheckerTest.php b/tests/src/Kernel/StatusCheck/StatusCheckerTest.php
index 3d0e4ec99558b3aa8be377e8268f38fc992d6373..af083d22d67258a2d6b437b2c720de2d822ccd56 100644
--- a/tests/src/Kernel/StatusCheck/StatusCheckerTest.php
+++ b/tests/src/Kernel/StatusCheck/StatusCheckerTest.php
@@ -4,8 +4,8 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\CronUpdater;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\CronUpdateStage;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\automatic_updates\Validation\StatusChecker;
 use Drupal\automatic_updates\Validator\ScaffoldFilePermissionsValidator;
 use Drupal\automatic_updates\Validator\StagedProjectsValidator;
@@ -210,12 +210,12 @@ class StatusCheckerTest extends AutomaticUpdatesKernelTestBase {
     $this->addEventTestListener($listener, StatusCheckEvent::class);
     $this->container->get(StatusChecker::class)->run();
     // By default, updates will be enabled on cron.
-    $this->assertInstanceOf(CronUpdater::class, $stage);
+    $this->assertInstanceOf(CronUpdateStage::class, $stage);
     $this->config('automatic_updates.settings')
-      ->set('cron', CronUpdater::DISABLED)
+      ->set('cron', CronUpdateStage::DISABLED)
       ->save();
     $this->container->get(StatusChecker::class)->run();
-    $this->assertInstanceOf(Updater::class, $stage);
+    $this->assertInstanceOf(UpdateStage::class, $stage);
   }
 
   /**
@@ -254,12 +254,12 @@ class StatusCheckerTest extends AutomaticUpdatesKernelTestBase {
     $event_dispatcher = $this->container->get('event_dispatcher');
     array_walk($validators, [$event_dispatcher, 'removeSubscriber']);
 
-    $updater = $this->container->get(Updater::class);
-    $updater->begin(['drupal' => '9.8.1']);
-    $updater->stage();
-    $updater->apply();
-    $updater->postApply();
-    $updater->destroy();
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin(['drupal' => '9.8.1']);
+    $stage->stage();
+    $stage->apply();
+    $stage->postApply();
+    $stage->destroy();
 
     // The status validation manager shouldn't have any stored results.
     $this->assertEmpty($manager->getResults());
diff --git a/tests/src/Kernel/StatusCheck/VersionPolicyValidatorTest.php b/tests/src/Kernel/StatusCheck/VersionPolicyValidatorTest.php
index 280e1a49ceb52666fd1596015543d9ad958a9105..9d8519c868869321f0ab5d93686d61366f6137d3 100644
--- a/tests/src/Kernel/StatusCheck/VersionPolicyValidatorTest.php
+++ b/tests/src/Kernel/StatusCheck/VersionPolicyValidatorTest.php
@@ -4,8 +4,8 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\CronUpdater;
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\CronUpdateStage;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\fixture_manipulator\ActiveFixtureManipulator;
 use Drupal\package_manager\Event\PreCreateEvent;
 use Drupal\package_manager\Exception\StageEventException;
@@ -41,7 +41,7 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       'stable release installed' => [
         '9.8.0',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::DISABLED, CronUpdater::SECURITY, CronUpdater::ALL],
+        [CronUpdateStage::DISABLED, CronUpdateStage::SECURITY, CronUpdateStage::ALL],
         [],
       ],
       // This case proves that updating from a dev snapshot is never allowed,
@@ -49,7 +49,7 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       'dev snapshot installed' => [
         '9.8.0-dev',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::DISABLED, CronUpdater::SECURITY, CronUpdater::ALL],
+        [CronUpdateStage::DISABLED, CronUpdateStage::SECURITY, CronUpdateStage::ALL],
         [
           $this->createVersionPolicyValidationResult('9.8.0-dev', NULL, [
             t('Drupal cannot be automatically updated from the installed version, 9.8.0-dev, because automatic updates from a dev version to any other version are not supported.'),
@@ -61,13 +61,13 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       'alpha installed, cron disabled' => [
         '9.8.0-alpha1',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::DISABLED],
+        [CronUpdateStage::DISABLED],
         [],
       ],
       'alpha installed, cron enabled' => [
         '9.8.0-alpha1',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::SECURITY, CronUpdater::ALL],
+        [CronUpdateStage::SECURITY, CronUpdateStage::ALL],
         [
           $this->createVersionPolicyValidationResult('9.8.0-alpha1', NULL, [
             t('Drupal cannot be automatically updated during cron from its current version, 9.8.0-alpha1, because it is not a stable version.'),
@@ -77,13 +77,13 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       'beta installed, cron disabled' => [
         '9.8.0-beta2',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::DISABLED],
+        [CronUpdateStage::DISABLED],
         [],
       ],
       'beta installed, cron enabled' => [
         '9.8.0-beta2',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::SECURITY, CronUpdater::ALL],
+        [CronUpdateStage::SECURITY, CronUpdateStage::ALL],
         [
           $this->createVersionPolicyValidationResult('9.8.0-beta2', NULL, [
             t('Drupal cannot be automatically updated during cron from its current version, 9.8.0-beta2, because it is not a stable version.'),
@@ -93,13 +93,13 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       'rc installed, cron disabled' => [
         '9.8.0-rc3',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::DISABLED],
+        [CronUpdateStage::DISABLED],
         [],
       ],
       'rc installed, cron enabled' => [
         '9.8.0-rc3',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::SECURITY, CronUpdater::ALL],
+        [CronUpdateStage::SECURITY, CronUpdateStage::ALL],
         [
           $this->createVersionPolicyValidationResult('9.8.0-rc3', NULL, [
             t('Drupal cannot be automatically updated during cron from its current version, 9.8.0-rc3, because it is not a stable version.'),
@@ -115,7 +115,7 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       'update to normal release' => [
         '9.8.1',
         "$metadata_dir/drupal.9.8.2.xml",
-        [CronUpdater::DISABLED, CronUpdater::SECURITY, CronUpdater::ALL],
+        [CronUpdateStage::DISABLED, CronUpdateStage::SECURITY, CronUpdateStage::ALL],
         [],
       ],
       // These three cases prove that updating from an unsupported minor version
@@ -127,13 +127,13 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       'update from unsupported minor, cron disabled' => [
         '9.7.1',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::DISABLED],
+        [CronUpdateStage::DISABLED],
         [],
       ],
       'update from unsupported minor, cron enabled, minor updates forbidden' => [
         '9.7.1',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::SECURITY, CronUpdater::ALL],
+        [CronUpdateStage::SECURITY, CronUpdateStage::ALL],
         [
           $this->createVersionPolicyValidationResult('9.7.1', NULL, [
             t('The currently installed version of Drupal core, 9.7.1, is not in a supported minor version. Your site will not be automatically updated during cron until it is updated to a supported minor version.'),
@@ -144,7 +144,7 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       'update from unsupported minor, cron enabled, minor updates allowed' => [
         '9.7.1',
         "$metadata_dir/drupal.9.8.1-security.xml",
-        [CronUpdater::SECURITY, CronUpdater::ALL],
+        [CronUpdateStage::SECURITY, CronUpdateStage::ALL],
         [
           $this->createVersionPolicyValidationResult('9.7.1', NULL, [
             t('The currently installed version of Drupal core, 9.7.1, is not in a supported minor version. Your site will not be automatically updated during cron until it is updated to a supported minor version.'),
@@ -165,9 +165,9 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
    *   The path of the core release metadata to serve to the update system.
    * @param string[] $cron_modes
    *   The modes for unattended updates. Can contain any of
-   *   \Drupal\automatic_updates\CronUpdater::DISABLED,
-   *   \Drupal\automatic_updates\CronUpdater::SECURITY, and
-   *   \Drupal\automatic_updates\CronUpdater::ALL.
+   *   \Drupal\automatic_updates\CronUpdateStage::DISABLED,
+   *   \Drupal\automatic_updates\CronUpdateStage::SECURITY, and
+   *   \Drupal\automatic_updates\CronUpdateStage::ALL.
    * @param \Drupal\package_manager\ValidationResult[] $expected_results
    *   The expected validation results.
    * @param bool $allow_minor_updates
@@ -210,8 +210,8 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
           ]),
         ],
       ],
-      // The following cases can only happen by explicitly supplying the updater
-      // with an invalid target version.
+      // The following cases can only happen by explicitly supplying the
+      // update stage with an invalid target version.
       'downgrade' => [
         '9.8.1',
         "$metadata_dir/drupal.9.8.2.xml",
@@ -290,7 +290,7 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
    * @param string $release_metadata
    *   The path of the core release metadata to serve to the update system.
    * @param string[] $project_versions
-   *   The desired project versions that should be passed to the updater.
+   *   The desired project versions that should be passed to the update stage.
    * @param \Drupal\package_manager\ValidationResult[] $expected_results
    *   The expected validation results.
    * @param bool $allow_minor_updates
@@ -307,14 +307,14 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
       ->set('allow_core_minor_updates', $allow_minor_updates)
       ->save();
 
-    $updater = $this->container->get(Updater::class);
+    $stage = $this->container->get(UpdateStage::class);
 
     try {
-      $updater->begin($project_versions);
+      $stage->begin($project_versions);
       // Ensure that we did not, in fact, expect any errors.
       $this->assertEmpty($expected_results);
-      // Reset the updater for the next iteration of the loop.
-      $updater->destroy();
+      // Reset the update stage for the next iteration of the loop.
+      $stage->destroy();
     }
     catch (StageEventException $e) {
       $this->assertExpectedResultsFromException($expected_results, $e);
@@ -360,11 +360,11 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
    * just in case it does, we need to be sure that it's an error condition.
    */
   public function testNoStagedPackageVersions(): void {
-    // Remove the stored package versions from the updater's metadata.
+    // Remove the stored package versions from the update stage's metadata.
     $listener = function (PreCreateEvent $event): void {
-      /** @var \Drupal\Tests\automatic_updates\Kernel\TestUpdater $updater */
-      $updater = $event->stage;
-      $updater->setMetadata('packages', [
+      /** @var \Drupal\Tests\automatic_updates\Kernel\TestUpdateStage $stage */
+      $stage = $event->stage;
+      $stage->setMetadata('packages', [
         'production' => [],
       ]);
     };
@@ -380,9 +380,9 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
   public function testNoCorePackagesInstalled(): void {
     $listener = function (PreCreateEvent $event): void {
       // We should have staged package versions.
-      /** @var \Drupal\automatic_updates\Updater $updater */
-      $updater = $event->stage;
-      $this->assertNotEmpty($updater->getPackageVersions());
+      /** @var \Drupal\automatic_updates\UpdateStage $stage */
+      $stage = $event->stage;
+      $this->assertNotEmpty($stage->getPackageVersions());
       // Remove all core packages in the active directory.
       (new ActiveFixtureManipulator())
         ->removePackage('drupal/core-recommended')
@@ -398,7 +398,7 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
    *
    * @param \Closure $listener
    *   A pre-create event listener to run before all validators. This should put
-   *   the test project and/or updater into a state which will cause
+   *   the test project and/or update stage into a state which will cause
    *   \Drupal\automatic_updates\Validator\VersionPolicyValidator::getTargetVersion()
    *   to throw an exception because the target version of Drupal core is not
    *   known.
@@ -408,7 +408,7 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
 
     $this->expectException(StageException::class);
     $this->expectExceptionMessage('The target version of Drupal core could not be determined.');
-    $this->container->get(Updater::class)
+    $this->container->get(UpdateStage::class)
       ->begin(['drupal' => '9.8.1']);
   }
 
diff --git a/tests/src/Kernel/StatusCheck/XdebugValidatorTest.php b/tests/src/Kernel/StatusCheck/XdebugValidatorTest.php
index fc522ded212ee0d17df106c344460fdbe8c9fd1e..6eed58c5708b77ffaaee2f04397b333b205bee30 100644
--- a/tests/src/Kernel/StatusCheck/XdebugValidatorTest.php
+++ b/tests/src/Kernel/StatusCheck/XdebugValidatorTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck;
 
-use Drupal\automatic_updates\CronUpdater;
+use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\Core\Logger\RfcLogLevel;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\package_manager\StatusCheckTrait;
@@ -40,7 +40,7 @@ class XdebugValidatorTest extends AutomaticUpdatesKernelTestBase {
     $config = $this->config('automatic_updates.settings');
     // If cron updates are disabled, the status check message should only be
     // a warning.
-    $config->set('cron', CronUpdater::DISABLED)->save();
+    $config->set('cron', CronUpdateStage::DISABLED)->save();
 
     // Tests that other projects which depend on Package manager also get the
     // warning.
@@ -58,8 +58,8 @@ class XdebugValidatorTest extends AutomaticUpdatesKernelTestBase {
     $this->assertCheckerResultsFromManager([$result], TRUE);
 
     // The parent class' setUp() method simulates an available security update,
-    // so ensure that the cron updater will try to update to it.
-    $config->set('cron', CronUpdater::SECURITY)->save();
+    // so ensure that the cron update stage will try to update to it.
+    $config->set('cron', CronUpdateStage::SECURITY)->save();
 
     // If cron updates are enabled the status check message should be an
     // error.
@@ -89,8 +89,8 @@ class XdebugValidatorTest extends AutomaticUpdatesKernelTestBase {
     $message = "Xdebug is enabled, currently Cron Updates are not allowed while it is enabled. If Xdebug is not disabled you will not receive security and other updates during cron.";
 
     // The parent class' setUp() method simulates an available security
-    // update, so ensure that the cron updater will try to update to it.
-    $this->config('automatic_updates.settings')->set('cron', CronUpdater::SECURITY)->save();
+    // update, so ensure that the cron update stage will try to update to it.
+    $this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
 
     // Trying to do the update during cron should fail with an error.
     $logger = new TestLogger();
diff --git a/tests/src/Kernel/UpdaterTest.php b/tests/src/Kernel/UpdateStageTest.php
similarity index 85%
rename from tests/src/Kernel/UpdaterTest.php
rename to tests/src/Kernel/UpdateStageTest.php
index 0526a2e979f76da90ae454331b754077efabdf83..e5a4476453b10625a83d39a7fa7396e801cb8d57 100644
--- a/tests/src/Kernel/UpdaterTest.php
+++ b/tests/src/Kernel/UpdateStageTest.php
@@ -4,7 +4,7 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\automatic_updates\Kernel;
 
-use Drupal\automatic_updates\Updater;
+use Drupal\automatic_updates\UpdateStage;
 use Drupal\package_manager\Exception\ApplyFailedException;
 use Drupal\package_manager\Exception\StageException;
 use Drupal\package_manager_bypass\LoggingCommitter;
@@ -12,11 +12,11 @@ use Drupal\Tests\user\Traits\UserCreationTrait;
 use PhpTuf\ComposerStager\Domain\Exception\InvalidArgumentException;
 
 /**
- * @coversDefaultClass \Drupal\automatic_updates\Updater
+ * @coversDefaultClass \Drupal\automatic_updates\UpdateStage
  * @group automatic_updates
  * @internal
  */
-class UpdaterTest extends AutomaticUpdatesKernelTestBase {
+class UpdateStageTest extends AutomaticUpdatesKernelTestBase {
 
   use UserCreationTrait;
 
@@ -52,7 +52,7 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
     $user = $this->createUser([], NULL, TRUE, ['uid' => 2]);
     $this->setCurrentUser($user);
 
-    $id = $this->container->get(Updater::class)->begin([
+    $id = $this->container->get(UpdateStage::class)->begin([
       'drupal' => '9.8.1',
     ]);
     // Rebuild the container to ensure the package versions are persisted.
@@ -63,7 +63,7 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
     // Keep using the user account we created.
     $this->setCurrentUser($user);
 
-    $updater = $this->container->get(Updater::class);
+    $stage = $this->container->get(UpdateStage::class);
 
     // Ensure that the target package versions are what we expect.
     $expected_versions = [
@@ -74,9 +74,9 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
         'drupal/core-dev' => '9.8.1',
       ],
     ];
-    $this->assertSame($expected_versions, $updater->claim($id)->getPackageVersions());
+    $this->assertSame($expected_versions, $stage->claim($id)->getPackageVersions());
 
-    // When we call Updater::stage(), the stored project versions should be
+    // When we call UpdateStage::stage(), the stored project versions should be
     // read from state and passed to Composer Stager's Stager service, in the
     // form of a Composer command. This is done using package_manager_bypass's
     // invocation recorder, rather than a regular mock, in order to test that
@@ -104,7 +104,7 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
         'drupal/core-dev:9.8.1',
       ],
     ];
-    $updater->stage();
+    $stage->stage();
 
     $actual_arguments = $this->container->get('package_manager.stager')
       ->getInvocationArguments();
@@ -123,7 +123,7 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
   public function testInvalidProjectVersions(array $project_versions): void {
     $this->expectException(\InvalidArgumentException::class);
     $this->expectExceptionMessage('Currently only updates to Drupal core are supported.');
-    $this->container->get(Updater::class)->begin($project_versions);
+    $this->container->get(UpdateStage::class)->begin($project_versions);
   }
 
   /**
@@ -176,11 +176,11 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
   public function testCommitException(string $thrown_class, string $expected_class = NULL): void {
     $this->getStageFixtureManipulator()->setCorePackageVersion('9.8.1');
 
-    $updater = $this->container->get(Updater::class);
-    $updater->begin([
+    $stage = $this->container->get(UpdateStage::class);
+    $stage->begin([
       'drupal' => '9.8.1',
     ]);
-    $updater->stage();
+    $stage->stage();
     $thrown_message = 'A very bad thing happened';
     LoggingCommitter::setException(new $thrown_class($thrown_message, 123));
     $this->expectException($expected_class);
@@ -189,15 +189,15 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
       : $thrown_message;
     $this->expectExceptionMessage($expected_message);
     $this->expectExceptionCode(123);
-    $updater->apply();
+    $stage->apply();
   }
 
   /**
-   * Tests that setLogger is called on the updater service.
+   * Tests that setLogger is called on the update stage service.
    */
   public function testLoggerIsSetByContainer(): void {
-    $updater_method_calls = $this->container->getDefinition('automatic_updates.updater')->getMethodCalls();
-    $this->assertSame('setLogger', $updater_method_calls[0][0]);
+    $stage_method_calls = $this->container->getDefinition('automatic_updates.update_stage')->getMethodCalls();
+    $this->assertSame('setLogger', $stage_method_calls[0][0]);
   }
 
 }