diff --git a/DLCM-ArchivalStorage/src/main/java/ch/dlcm/controller/archivalstorage/AIPController.java b/DLCM-ArchivalStorage/src/main/java/ch/dlcm/controller/archivalstorage/AIPController.java
index 89280e2b81601484b619daabc914b67c46a0e243..ece1673f6778402befabef66b82acccde63337af 100644
--- a/DLCM-ArchivalStorage/src/main/java/ch/dlcm/controller/archivalstorage/AIPController.java
+++ b/DLCM-ArchivalStorage/src/main/java/ch/dlcm/controller/archivalstorage/AIPController.java
@@ -456,6 +456,12 @@ public class AIPController extends AbstractPackageController<AipDataFile, Archiv
     return this.changeAipStatus(PackageStatus.METADATA_UPGRADE_PENDING, aipId);
   }
 
+  @PostMapping(SolidifyConstants.URL_ID_PLUS_SEP + DLCMActionName.START_COMPLIANCE_LEVEL_UPDATE)
+  @TrustedUserPermissions
+  public HttpEntity<Result> updateComplianceLevel(@PathVariable("id") String aipId) {
+    return this.changeAipStatus(PackageStatus.COMPLIANCE_LEVEL_UPDATE_PENDING, aipId);
+  }
+
   @Override
   protected <W extends RepresentationModel<W>> void addOthersLinks(W w) {
     w.add(Tool.filter(linkTo(this.getClass()).toUriComponentsBuilder(), DLCMConstants.ARCHIVAL_UNIT_PARAM, "true")
@@ -550,12 +556,14 @@ public class AIPController extends AbstractPackageController<AipDataFile, Archiv
     final Result result = new Result(aipId);
     if (currentStatus == PackageStatus.COMPLETED
             && (newStatus == PackageStatus.METADATA_EDITION_PENDING
-            || newStatus == PackageStatus.METADATA_UPGRADE_PENDING)) {
+                    || newStatus == PackageStatus.METADATA_UPGRADE_PENDING
+                    || newStatus == PackageStatus.COMPLIANCE_LEVEL_UPDATE_PENDING)) {
       aip.getInfo().setStatus(newStatus);
       aip = this.itemService.save(aip);
       result.setStatus(Result.ActionStatus.EXECUTED);
       result.setMesssage(this.messageService.get("message.aip.status"));
-      if (newStatus == PackageStatus.METADATA_UPGRADE_PENDING) {
+      if (newStatus == PackageStatus.METADATA_UPGRADE_PENDING
+              || newStatus == PackageStatus.COMPLIANCE_LEVEL_UPDATE_PENDING) {
         ((ArchivalInfoPackageService) this.itemService).putPackageInProcessingQueue(aip);
       }
       return new ResponseEntity<>(result, HttpStatus.OK);
diff --git a/DLCM-ArchivalStorage/src/main/java/ch/dlcm/service/AipStatusService.java b/DLCM-ArchivalStorage/src/main/java/ch/dlcm/service/AipStatusService.java
index 0c7983b2b379fef04f63ab774b12e6f37daaa198..937eef307f2342f4ec6bb511774ae6b7b23d1ace 100644
--- a/DLCM-ArchivalStorage/src/main/java/ch/dlcm/service/AipStatusService.java
+++ b/DLCM-ArchivalStorage/src/main/java/ch/dlcm/service/AipStatusService.java
@@ -172,6 +172,8 @@ public class AipStatusService extends AbstractAipService {
         case EDITING_METADATA -> this.updateMetadata(aip);
         case METADATA_UPGRADE_PENDING -> this.startMetadataUpgradeAip(aip);
         case UPGRADING_METADATA -> this.upgradeMetadata(aip);
+        case COMPLIANCE_LEVEL_UPDATE_PENDING -> this.startComplianceLevelUpdateAip(aip);
+        case UPDATING_COMPLIANCE_LEVEL -> this.updateComplianceLevel(aip);
 
         default -> throw new SolidifyRuntimeException(
                 this.messageService.get("archival.aip.error.status", new Object[] { aip.getInfo().getStatus() }));
@@ -390,6 +392,32 @@ public class AipStatusService extends AbstractAipService {
     }
   }
 
+  // AIP with COMPLIANCE_LEVEL_UPDATE_PENDING status
+  private void startComplianceLevelUpdateAip(ArchivalInfoPackage aip) {
+    // Start AIP metadata edition
+    aip.setPackageStatus(PackageStatus.UPDATING_COMPLIANCE_LEVEL);
+    this.logPackageMessage(LogLevel.INFO, aip, "compliance level updating is starting");
+  }
+
+  // AIP with UPDATING_COMPLIANCE_LEVEL status
+  private void updateComplianceLevel(ArchivalInfoPackage aip) {
+    try {
+      if (this.storageService.updateComplianceLevel(aip) > 0) {
+        this.updateAipWithNewPackage(aip);
+        aip.setPackageStatus(PackageStatus.REINDEXING);
+        aip.setLastArchiving(OffsetDateTime.now());
+      } else {
+        this.completeAip(aip);
+      }
+    } catch (IOException e) {
+      throw new SolidifyRuntimeException("IOException during AIP compliance level update", e);
+    } catch (JAXBException e) {
+      throw new SolidifyRuntimeException("JAXBException during AIP compliance level update", e);
+    } catch (NoSuchAlgorithmException | URISyntaxException e) {
+      throw new SolidifyRuntimeException("NoSuchAlgorithmException | URISyntaxException during AIP metadata update", e);
+    }
+  }
+
   // AIP with PACKAGE_REPLICATION_PENDING status
   private void startReplicationPackageAip(ArchivalInfoPackage aip) {
     // Start AIP package replication
diff --git a/DLCM-ArchivalStorage/src/main/java/ch/dlcm/storage/StorageService.java b/DLCM-ArchivalStorage/src/main/java/ch/dlcm/storage/StorageService.java
index f30cad1cf5a4e70702d48ce844459a3f710b137a..2a21b24a1983af34fdd4d8f80bda51e94a0c7f64 100644
--- a/DLCM-ArchivalStorage/src/main/java/ch/dlcm/storage/StorageService.java
+++ b/DLCM-ArchivalStorage/src/main/java/ch/dlcm/storage/StorageService.java
@@ -54,6 +54,8 @@ import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 
 import ch.unige.solidify.ChecksumAlgorithm;
+import ch.unige.solidify.SolidifyConstants;
+import ch.unige.solidify.config.SolidifyEventPublisher;
 import ch.unige.solidify.exception.SolidifyCheckingException;
 import ch.unige.solidify.exception.SolidifyProcessingException;
 import ch.unige.solidify.service.MessageService;
@@ -74,6 +76,7 @@ import ch.dlcm.model.FileInfoUpdate;
 import ch.dlcm.model.IdentifierType;
 import ch.dlcm.model.Package;
 import ch.dlcm.model.PackageStatus;
+import ch.dlcm.model.StatusHistory;
 import ch.dlcm.model.StoredArchiveInterface;
 import ch.dlcm.model.index.ArchiveMetadata;
 import ch.dlcm.model.index.ArchivePublicData;
@@ -248,8 +251,6 @@ public abstract class StorageService extends DLCMService {
     // Check & extract archive
     final Path aipPackageFolder = Paths.get(this.checkPackage(aip, false, false));
     final Path aipDataFolder = this.getDataFolder(aip.getArchiveContainer(), aipPackageFolder);
-    // Get updated folder
-    final Path aipUpdateFolder = this.getAIPFolder(aip.getResId()).resolve(DLCMConstants.UPDATE_FOLDER);
     // Migrate metadata
     MetadataMigrationTool.migrateMetadataToDefaultVersion(aip.getInfo().getMetadataVersion(),
             aipDataFolder.resolve(Package.METADATA_FILE.getName()));
@@ -262,10 +263,6 @@ public abstract class StorageService extends DLCMService {
     if (FileTool.checkFile(aipPackageFolder) && !FileTool.deleteFolder(aipPackageFolder)) {
       throw new DLCMPreservationException(this.messageService.get(AIP_ERROR_PURGE_FILES_MSG));
     }
-    // Purge update folder (temporary folder for archive files)
-    if (FileTool.checkFile(aipUpdateFolder) && !FileTool.deleteFolder(aipUpdateFolder)) {
-      throw new DLCMPreservationException(this.messageService.get(AIP_ERROR_PURGE_FILES_MSG));
-    }
     // Set the archive size
     aip.setArchiveSize(FileTool.getSize(newPackageFile));
     aip.setArchiveFileNumber(aip.getArchiveFileNumber() + 1); // add one to ArchiveFileNumber as we create xml file every time we do an update
@@ -275,6 +272,45 @@ public abstract class StorageService extends DLCMService {
     aip.incrementUpdateNumber();
   }
 
+  // Update compliance level
+  public int updateComplianceLevel(ArchivalInfoPackage aip) throws IOException, JAXBException, URISyntaxException {
+    // Check & extract archive
+    final Path aipPackageFolder = Paths.get(this.checkPackage(aip, false, false));
+    final Path aipDataFolder = this.getDataFolder(aip.getArchiveContainer(), aipPackageFolder);
+    final Path metadataXml = aipDataFolder.resolve(Package.METADATA_FILE.getName());
+    // Copy original metadata XML file
+    final Path originalXml = metadataXml.getParent()
+            .resolve(metadataXml.getFileName().toString()
+                    .replaceFirst(SolidifyConstants.XML_EXT,
+                            "-" + OffsetDateTime.now().format(DateTimeFormatter.ofPattern(StringTool.DATE_TIME_FORMAT_FOR_FILE))
+                                    + SolidifyConstants.XML_EXT));
+    if (!FileTool.copyFile(metadataXml, originalXml)) {
+      throw new SolidifyProcessingException(
+              this.messageService.get("archival.aip.error.metadata-copy", new Object[] { metadataXml, originalXml }));
+    }
+    // Upgrade metadata by adding Premis event
+    final int updateNumber = this.metadataService.updateComplianceLevel(aip,
+            aipPackageFolder.resolve(this.getMetadataRelativePath(aip.getArchiveContainer())));
+    if (updateNumber > 0) {
+      this.updateHistory(aip, PackageStatus.COMPLIANCE_LEVEL_UPDATED.toString(),
+              this.messageService.get("archival.aip.compliance-updated", new Object[] { updateNumber }));
+      // Generate new package
+      final Path newPackageFile = this.generateNewPackage(aip, aipDataFolder);
+      // Set the archive size
+      aip.setArchiveSize(FileTool.getSize(newPackageFile));
+      aip.setArchiveFileNumber(aip.getArchiveFileNumber() + 1); // add one to ArchiveFileNumber as we create xml file every time we do an update
+      // Save new archive
+      this.replaceAIP(aip, newPackageFile);
+      // Add update
+      aip.incrementUpdateNumber();
+    }
+    // Purge package folder (temporary folder for updating archive )
+    if (FileTool.checkFile(aipPackageFolder) && !FileTool.deleteFolder(aipPackageFolder)) {
+      throw new DLCMPreservationException(this.messageService.get(AIP_ERROR_PURGE_FILES_MSG));
+    }
+    return updateNumber;
+  }
+
   // *********************
   // ** Default Methods **
   // *********************
@@ -762,6 +798,12 @@ public abstract class StorageService extends DLCMService {
     }
   }
 
+  protected void updateHistory(ArchivalInfoPackage aip, String status, String description) {
+    final StatusHistory stsHistory = new StatusHistory(aip.getClass().getSimpleName(), aip.getResId(), status);
+    stsHistory.setDescription(description);
+    SolidifyEventPublisher.getPublisher().publishEvent(stsHistory);
+  }
+
   // *********************
   // ** Private Methods **
   // *********************
@@ -1084,7 +1126,8 @@ public abstract class StorageService extends DLCMService {
     // First check premis data category anda datatype to take the file object according to it.
     List<Object> itemList = (List<Object>) ((Map<String, Object>) ((Map<String, Object>) archiveMetadata.getMetadata()
             .get(DLCMConstants.PREMIS_FIELD))
-            .get(DLCMConstants.ITEMS_FIELD)).get(DLCMConstants.ITEM_FIELD);
+                    .get(DLCMConstants.ITEMS_FIELD))
+                            .get(DLCMConstants.ITEM_FIELD);
     for (Object obj : itemList) {
       Map<String, Object> item = ((Map<String, Object>) obj);
       if (item.get(DLCMConstants.TYPE_FIELD).equals("dataFile")) {
@@ -1152,8 +1195,8 @@ public abstract class StorageService extends DLCMService {
     // Check all files from thumbnail, readme and dua extension and check if their timestamp from the filename is later from the last time
     // the aip was completed, meaning the file has being updated since.
     List<Path> filesToUpdated = allUpdatedFiles.stream().filter(file -> file.getFileName().toString().endsWith(DLCMConstants.THUMBNAIL_EXTENSION)
-                    || file.getFileName().toString().endsWith(DLCMConstants.README_EXTENSION)
-                    || file.getFileName().toString().endsWith(DLCMConstants.DUA_EXTENSION))
+            || file.getFileName().toString().endsWith(DLCMConstants.README_EXTENSION)
+            || file.getFileName().toString().endsWith(DLCMConstants.DUA_EXTENSION))
             .filter(file -> {
               String timestamp = file.getFileName().toString()
                       .substring(file.getFileName().toString().indexOf("-") + 1, file.getFileName().toString().lastIndexOf("."));
diff --git a/DLCM-Common/src/main/resources/locale/messages_dlcm.properties b/DLCM-Common/src/main/resources/locale/messages_dlcm.properties
index c279365837511081264daa85762e559cef46810b..e6bbe155983d209a0da2f05c68e40ed2c5c6cc89 100644
--- a/DLCM-Common/src/main/resources/locale/messages_dlcm.properties
+++ b/DLCM-Common/src/main/resources/locale/messages_dlcm.properties
@@ -206,8 +206,8 @@ preingest.deposit.status.cancel_editing_metadata=Cancel editing metadata
 preingest.deposit.status.cleaning=Cleaning
 preingest.deposit.status.cleaned=Cleaned
 preingest.deposit.status.deleting=Deposit being deleted
-preingest.deposit.status.checking_compliance=Checking compliance level
-preingest.deposit.status.error_in_processing=Error when processing internat treatment for the deposit
+preingest.deposit.status.checking_compliance=Checking compliance levels
+preingest.deposit.status.error_in_processing=Error when processing internal treatment for the deposit
 preingest.deposit.status.editing_metadata_rejected=Editing metadata was rejected
 preingest.deposit.status.upgrading_metadata=Upgrading metadata version to the latest
 preingest.deposit.datafile.notready=Data files of deposit are not ready
@@ -237,6 +237,8 @@ ingest.notification.sip.datafile.error=Data files of the SIP {0} are in error
 archival.aip.completed=The AIP package with ID {0} is already completed
 archival.aip.forever=The AIP package with ID {0} is archived forever
 archival.aip.retention=The AIP package with ID {0} is not ready for disposition
+archival.aip.compliance-updated=Archive compliance levels updated ({0})
+archival.aip.error.metadata-copy=Cannot copy the original metadata file: {0} => {1}
 archival.aip.error.collection=A collection cannot be downloaded
 archival.aip.error.check=During the checking
 archival.aip.error.process=During the processing
@@ -361,6 +363,8 @@ package.status.fixing=Fixing
 package.status.fixity_error=Fixity error
 package.status.metadata_upgrade_pending=Metadata version upgrade pending
 package.status.upgrading_metadata=Upgrading metadata version to the latest
+package.status.compliance_level_update_pending=Compliance level update pending
+package.status.updating_compliance_level=Updating archive compliance levels
 package.error.check_directory=Problem with package directory ({0}) in {1}
 #############
 # Data file #
@@ -391,10 +395,10 @@ datafile.status.processed=Downloaded
 datafile.status.ready=Ready
 datafile.status.cleaning=Cleaning
 datafile.status.cleaned=Cleaned
-datafile.status.check_compliance=Check compliance level
-datafile.status.check_compliance_clean=Check compliance level for cleaned data file
-datafile.status.checked_compliance=Checked compliance level
-datafile.status.checked_compliance_clean=Checked compliance level for cleaned data file
+datafile.status.check_compliance=Check compliance levels
+datafile.status.check_compliance_clean=Check compliance levels for cleaned data file
+datafile.status.checked_compliance=Checked compliance levels
+datafile.status.checked_compliance_clean=Checked compliance levels for cleaned data file
 datafile.status.change_relative_location=Change relative location
 datafile.status.change_data_category=Change data category
 datafile.status.file_format_unknown=No found format by {0}
diff --git a/DLCM-Ingest/src/main/java/ch/dlcm/controller/ingest/SIPController.java b/DLCM-Ingest/src/main/java/ch/dlcm/controller/ingest/SIPController.java
index 59e0fe95ad50faf8a61294ae4f0e53b5c5ec5c45..ea69099a93aceafe0525b683e8fab3fe343cf50e 100644
--- a/DLCM-Ingest/src/main/java/ch/dlcm/controller/ingest/SIPController.java
+++ b/DLCM-Ingest/src/main/java/ch/dlcm/controller/ingest/SIPController.java
@@ -314,6 +314,7 @@ public class SIPController extends AbstractPackageController<SipDataFile, Submis
     SubmissionInfoPackage sip = this.itemService.findOne(id);
     final PackageStatus currentStatus = sip.getInfo().getStatus();
     final Result result = new Result(id);
+
     if ((newStatus == EDITING_METADATA && (currentStatus == PackageStatus.COMPLETED || currentStatus == PackageStatus.CLEANED))
             || (newStatus == PackageStatus.UPGRADING_METADATA
                     && currentStatus == PackageStatus.CLEANED
diff --git a/DLCM-Model/src/main/java/ch/dlcm/model/PackageStatus.java b/DLCM-Model/src/main/java/ch/dlcm/model/PackageStatus.java
index 4183e520e1a39de9f434ca710e3a60863bc98716..01b0c9b4c17d97fb0fdbc2f9cc544a521670e1b4 100644
--- a/DLCM-Model/src/main/java/ch/dlcm/model/PackageStatus.java
+++ b/DLCM-Model/src/main/java/ch/dlcm/model/PackageStatus.java
@@ -32,6 +32,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
         - CHECK_PENDING => A package verification is pending during checking process
         - CLEANED => Cleaned package during cleaning process for SIP only
         - CLEANING => A package clean is in progress during cleaning process for SIP only
+        - COMPLIANCE_LEVEL_UPDATE_PENDING => A package compliance update is pending
+        - COMPLIANCE_LEVEL_UPDATED => The compliance levels of the package have been updated
         - COMPLETED => Completed package
         - DISPOSABLE => The Package is candidate for disposal process for AIP only
         - DISPOSAL_APPROVED_BY_ORGUNIT => Disposal org. unit approval done during disposal process for AIP only
@@ -58,6 +60,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
         - RESUBMITTING => A package re-submission is in progress
         - STORED => Package stored on storage location
         - TOMBSTONE_REPLICATION_PENDING => A tombstone replication is pending
+        - UPDATING_COMPLIANCE_LEVEL => A package compliance update is in progress
         - UPDATING_RETENTION => A package retention update is in progress during disposal process
         - UPGRADING_METADATA => A metadata version upgrade is in progress
         """)
@@ -71,6 +74,7 @@ public enum PackageStatus {
   FIX_PENDING, FIXING,
   METADATA_EDITION_PENDING, EDITING_METADATA, UPDATING_RETENTION,
   METADATA_UPGRADE_PENDING, UPGRADING_METADATA,
+  COMPLIANCE_LEVEL_UPDATE_PENDING, UPDATING_COMPLIANCE_LEVEL,COMPLIANCE_LEVEL_UPDATED,
   REINDEXING,
   RELOADED,
   RESUBMITTING,
@@ -146,6 +150,11 @@ public enum PackageStatus {
             || status == PackageStatus.UPGRADING_METADATA);
   }
 
+  public static boolean isComplianceUpdateProcess(PackageStatus status) {
+    return (status == PackageStatus.COMPLIANCE_LEVEL_UPDATE_PENDING
+            || status == PackageStatus.UPDATING_COMPLIANCE_LEVEL);
+  }
+
   public static boolean isInProgress(PackageStatus status) {
     return (!isInError(status) && !isCompletedProcess(status) && !isDisposable(status));
   }
diff --git a/DLCM-Model/src/main/java/ch/dlcm/model/preservation/JobType.java b/DLCM-Model/src/main/java/ch/dlcm/model/preservation/JobType.java
index f0edb676ee6e2e4a05a227fcffc5ea94dcb642ad..b3798305af8bea1df1c9a89c8b2f57c79a107ae0 100644
--- a/DLCM-Model/src/main/java/ch/dlcm/model/preservation/JobType.java
+++ b/DLCM-Model/src/main/java/ch/dlcm/model/preservation/JobType.java
@@ -36,6 +36,7 @@ public enum JobType {
   ARCHIVE_PRELOAD_SMALL("Archive [small size] Preloading", true, true),
   CHECK_COMPLIANCE_LEVEL("Check compliance level", true, true),
   CLEAN_SUBMISSION("Clean Submission", true, true),
+  COMPLIANCE_LEVEL_UPDATE("Compliance Level Update", false, true),
   DISPOSAL("Trigger Disposal Processes", true, true),
   FIXITY("Fixity", true, true),
   METADATA_MIGRATION("Metadata Version Migration", false, true),
diff --git a/DLCM-Model/src/main/java/ch/dlcm/model/tool/MetadataMigrationTool.java b/DLCM-Model/src/main/java/ch/dlcm/model/tool/MetadataMigrationTool.java
index 771c9cf45d0e7ef0f2214769b08ab76d73ff40ff..d11848bd2eeb22d61f79100f7da2548ab5ce721c 100644
--- a/DLCM-Model/src/main/java/ch/dlcm/model/tool/MetadataMigrationTool.java
+++ b/DLCM-Model/src/main/java/ch/dlcm/model/tool/MetadataMigrationTool.java
@@ -56,7 +56,7 @@ public class MetadataMigrationTool {
     if (!FileTool.copyFile(metadataXml, originalXml)) {
       throw new SolidifyProcessingException("Cannot copy the original metadata file: " + metadataXml + " => " + originalXml);
     }
-    // Migrate the metadat
+    // Migrate the metadata
     DLCMMetadataVersion fromVersion = version;
     do {
       final DLCMMetadataVersion toVersion = MetadataMigrationTool.getMigrationPath().get(fromVersion);
diff --git a/DLCM-Model/src/main/java/ch/dlcm/rest/DLCMActionName.java b/DLCM-Model/src/main/java/ch/dlcm/rest/DLCMActionName.java
index ce5d27a22a18131b7492123be17b8861908b53f7..5999ab5200157f622e8161f8ed1c16617ca9558f 100644
--- a/DLCM-Model/src/main/java/ch/dlcm/rest/DLCMActionName.java
+++ b/DLCM-Model/src/main/java/ch/dlcm/rest/DLCMActionName.java
@@ -86,6 +86,7 @@ public class DLCMActionName {
   public static final String PREPARE_DOWNLOAD = "prepare-download";
   public static final String START_METADATA_EDITING = "start-metadata-editing";
   public static final String START_METADATA_UPGRADE = "start-metadata-upgrade";
+  public static final String START_COMPLIANCE_LEVEL_UPDATE = "start-compliance-level-update";
   public static final String SET_APPROVED = "set-approved";
   public static final String SET_REFUSED = "set-refused";
   public static final String SET_PENDING = "set-pending";
diff --git a/DLCM-Model/src/main/resources/scripts/upgrade22to30.sql b/DLCM-Model/src/main/resources/scripts/upgrade22to30.sql
index 7344689fda83f9502f0656a5d1e9fdae6bdf2bb1..1e85a1af3dddb4e6563be8e9f7ab462b6a13c989 100644
--- a/DLCM-Model/src/main/resources/scripts/upgrade22to30.sql
+++ b/DLCM-Model/src/main/resources/scripts/upgrade22to30.sql
@@ -33,7 +33,7 @@ ALTER TABLE `additional_fields_form`
 
 -- aip
 ALTER TABLE `aip`
-    MODIFY COLUMN `status` enum('CHECK_PENDING','CHECKING','CHECKED','CLEANING','CLEANED','COMPLETED','DOWNLOADING','IN_PREPARATION','IN_PROGRESS','STORED','INDEXING','READY','IN_ERROR','PRESERVATION_ERROR','DISPOSABLE','DISPOSAL_APPROVED_BY_ORGUNIT','DISPOSAL_APPROVED','DISPOSED','FIX_PENDING','FIXING','METADATA_EDITION_PENDING','EDITING_METADATA','UPDATING_RETENTION','REINDEXING','RELOADED','RESUBMITTING','PACKAGE_REPLICATION_PENDING','REPLICATING_PACKAGE','TOMBSTONE_REPLICATION_PENDING','REPLICATING_TOMBSTONE', 'METADATA_UPGRADE_PENDING', 'UPGRADING_METADATA') DEFAULT NULL;
+    MODIFY COLUMN `status` enum('CHECK_PENDING','CHECKING','CHECKED','CLEANING','CLEANED','COMPLETED','DOWNLOADING','IN_PREPARATION','IN_PROGRESS','STORED','INDEXING','READY','IN_ERROR','PRESERVATION_ERROR','DISPOSABLE','DISPOSAL_APPROVED_BY_ORGUNIT','DISPOSAL_APPROVED','DISPOSED','FIX_PENDING','FIXING','METADATA_EDITION_PENDING','EDITING_METADATA','UPDATING_RETENTION','REINDEXING','RELOADED','RESUBMITTING','PACKAGE_REPLICATION_PENDING','REPLICATING_PACKAGE','TOMBSTONE_REPLICATION_PENDING','REPLICATING_TOMBSTONE', 'METADATA_UPGRADE_PENDING', 'UPGRADING_METADATA', 'COMPLIANCE_LEVEL_UPDATE_PENDING', 'UPDATING_COMPLIANCE_LEVEL') DEFAULT NULL;
 ALTER TABLE `aip`
     MODIFY COLUMN `data_sensitivity` enum('UNDEFINED','BLUE','GREEN','YELLOW','ORANGE','RED','CRIMSON') DEFAULT NULL;
 ALTER TABLE `aip`
diff --git a/DLCM-Model/src/main/resources/xslt/dlcm4migration-1.0-1.1.xsl b/DLCM-Model/src/main/resources/xslt/dlcm4migration-1.0-1.1.xsl
index cd37d0fdbbdc866cb86eb76339fb710ac95a4de3..c2cbb879b27ecb56637939d092ed6e08d1b7b282 100644
--- a/DLCM-Model/src/main/resources/xslt/dlcm4migration-1.0-1.1.xsl
+++ b/DLCM-Model/src/main/resources/xslt/dlcm4migration-1.0-1.1.xsl
@@ -14,12 +14,16 @@
 
 	<!-- METS PROFILE -->
 	<xsl:template match="mets:mets/@PROFILE">
-		<xsl:attribute name="PROFILE"><xsl:text>dlcm_profile-1.1.xml</xsl:text></xsl:attribute>
+		<xsl:attribute name="PROFILE">
+			<xsl:text>dlcm_profile-1.1.xml</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 	<!-- METS MDTYPEVERSION -->
 	<xsl:template match="mets:mets/mets:dmdSec/mets:mdWrap/@MDTYPEVERSION">
-		<xsl:attribute name="MDTYPEVERSION"><xsl:text>DataCite Metadata Schema 4.0 (dlcm_datacite-1.0.xsd)</xsl:text></xsl:attribute>
+		<xsl:attribute name="MDTYPEVERSION">
+			<xsl:text>DataCite Metadata Schema 4.0 (dlcm_datacite-1.0.xsd)</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 </xsl:stylesheet>
diff --git a/DLCM-Model/src/main/resources/xslt/dlcm4migration-1.1-2.0.xsl b/DLCM-Model/src/main/resources/xslt/dlcm4migration-1.1-2.0.xsl
index 0a079b79d595a6493f7ea3bc04efa7540556637f..4abac31f7f9df838698f17d7c6b3b4869e8b6cf4 100644
--- a/DLCM-Model/src/main/resources/xslt/dlcm4migration-1.1-2.0.xsl
+++ b/DLCM-Model/src/main/resources/xslt/dlcm4migration-1.1-2.0.xsl
@@ -53,12 +53,16 @@
 
 	<!-- Migrate METS Profile -->
 	<xsl:template match="mets:mets/@PROFILE">
-		<xsl:attribute name="PROFILE"><xsl:text>dlcm_profile-2.0.xml</xsl:text></xsl:attribute>
+		<xsl:attribute name="PROFILE"
+			><xsl:text>dlcm_profile-2.0.xml</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 	<!-- Migrate METS MDTYPEVERSION -->
 	<xsl:template match="mets:mets/mets:dmdSec/mets:mdWrap/@MDTYPEVERSION">
-		<xsl:attribute name="MDTYPEVERSION"><xsl:text>DataCite Metadata Schema 4.3 (dlcm_datacite-2.0.xsd)</xsl:text></xsl:attribute>
+		<xsl:attribute name="MDTYPEVERSION">
+			<xsl:text>DataCite Metadata Schema 4.3 (dlcm_datacite-2.0.xsd)</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 	<!-- Add DataCite 'nameType' attribute for each 'datacite:creatorName' -->
diff --git a/DLCM-Model/src/main/resources/xslt/dlcm4migration-2.0-2.1.xsl b/DLCM-Model/src/main/resources/xslt/dlcm4migration-2.0-2.1.xsl
index 5a2762ba73a63d2f6ec4d96da90b001158bf85d0..ab1abb1252a32ff5ede1cdd31f67158adc9459df 100644
--- a/DLCM-Model/src/main/resources/xslt/dlcm4migration-2.0-2.1.xsl
+++ b/DLCM-Model/src/main/resources/xslt/dlcm4migration-2.0-2.1.xsl
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xmlns:mets="http://www.loc.gov/METS/" xmlns:datacite="http://datacite.org/schema/kernel-4" xmlns:premis="http://www.loc.gov/premis/v3"
-	xmlns:dlcm="http://www.dlcm.ch/dlcm/v2" xmlns:fits="http://hul.harvard.edu/ois/xml/ns/fits/fits_output" exclude-result-prefixes="datacite">
+	xmlns:dlcm="http://www.dlcm.ch/dlcm/v2" xmlns:fits="http://hul.harvard.edu/ois/xml/ns/fits/fits_output">
 
 	<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="UTF-8" />
 
@@ -14,12 +14,16 @@
 
 	<!-- METS Profile -->
 	<xsl:template match="mets:mets/@PROFILE">
-		<xsl:attribute name="PROFILE"><xsl:text>dlcm_profile-2.1.xml</xsl:text></xsl:attribute>
+		<xsl:attribute name="PROFILE">
+			<xsl:text>dlcm_profile-2.1.xml</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 	<!-- METS MDTYPEVERSION -->
 	<xsl:template match="mets:mets/mets:dmdSec/mets:mdWrap/@MDTYPEVERSION">
-		<xsl:attribute name="MDTYPEVERSION"><xsl:text>DataCite Metadata Schema 4.3 (dlcm_datacite-2.0.xsd)</xsl:text></xsl:attribute>
+		<xsl:attribute name="MDTYPEVERSION">
+			<xsl:text>DataCite Metadata Schema 4.3 (dlcm_datacite-2.0.xsd)</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 </xsl:stylesheet>
diff --git a/DLCM-Model/src/main/resources/xslt/dlcm4migration-2.1-3.0.xsl b/DLCM-Model/src/main/resources/xslt/dlcm4migration-2.1-3.0.xsl
index c3330ebb1543596166e64901cd4bddf5f1be0304..9abdff5703e69cb04c54b07187946a301921f1ab 100644
--- a/DLCM-Model/src/main/resources/xslt/dlcm4migration-2.1-3.0.xsl
+++ b/DLCM-Model/src/main/resources/xslt/dlcm4migration-2.1-3.0.xsl
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xmlns:mets="http://www.loc.gov/METS/" xmlns:datacite="http://datacite.org/schema/kernel-4" xmlns:premis="http://www.loc.gov/premis/v3"
-	xmlns:dlcm="http://www.dlcm.ch/dlcm/v2" xmlns:fits="http://hul.harvard.edu/ois/xml/ns/fits/fits_output" exclude-result-prefixes="">
+	xmlns:dlcm="http://www.dlcm.ch/dlcm/v2" xmlns:fits="http://hul.harvard.edu/ois/xml/ns/fits/fits_output">
 
 	<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="UTF-8" />
 
@@ -14,12 +14,16 @@
 
 	<!-- METS Profile -->
 	<xsl:template match="mets:mets/@PROFILE">
-		<xsl:attribute name="PROFILE"><xsl:text>dlcm_profile-3.0.xml</xsl:text></xsl:attribute>
+		<xsl:attribute name="PROFILE">
+			<xsl:text>dlcm_profile-3.0.xml</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 	
 	<!-- METS MDTYPEVERSION -->
 	<xsl:template match="mets:mets/mets:dmdSec/mets:mdWrap/@MDTYPEVERSION">
-		<xsl:attribute name="MDTYPEVERSION"><xsl:text>DataCite Metadata Schema 4.4 (dlcm_datacite-3.0.xsd)</xsl:text></xsl:attribute>
+		<xsl:attribute name="MDTYPEVERSION">
+			<xsl:text>DataCite Metadata Schema 4.4 (dlcm_datacite-3.0.xsd)</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 	
 </xsl:stylesheet>
diff --git a/DLCM-Model/src/main/resources/xslt/dlcm4migration-3.0-3.1.xsl b/DLCM-Model/src/main/resources/xslt/dlcm4migration-3.0-3.1.xsl
index 359a7ea7c210a73556a0311e17e80a6bed59cdee..72fa63902da07090df7b8289dc83dfd5465a9d27 100644
--- a/DLCM-Model/src/main/resources/xslt/dlcm4migration-3.0-3.1.xsl
+++ b/DLCM-Model/src/main/resources/xslt/dlcm4migration-3.0-3.1.xsl
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xmlns:mets="http://www.loc.gov/METS/" xmlns:datacite="http://datacite.org/schema/kernel-4" xmlns:premis="http://www.loc.gov/premis/v3"
-	xmlns:dlcm="http://www.dlcm.ch/dlcm/v2" xmlns:fits="http://hul.harvard.edu/ois/xml/ns/fits/fits_output" exclude-result-prefixes="">
+	xmlns:dlcm="http://www.dlcm.ch/dlcm/v2" xmlns:fits="http://hul.harvard.edu/ois/xml/ns/fits/fits_output">
 
 	<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="UTF-8" />
 
@@ -14,7 +14,9 @@
 
 	<!-- METS Profile -->
 	<xsl:template match="mets:mets/@PROFILE">
-		<xsl:attribute name="PROFILE"><xsl:text>dlcm_profile-3.1.xml</xsl:text></xsl:attribute>
+		<xsl:attribute name="PROFILE">
+			<xsl:text>dlcm_profile-3.1.xml</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 </xsl:stylesheet>
diff --git a/DLCM-Model/src/main/resources/xslt/dlcm4migration-3.1-4.0.xsl b/DLCM-Model/src/main/resources/xslt/dlcm4migration-3.1-4.0.xsl
index 3acefd88741909e0b0a933a7446ed899848f754f..43156f814cd77255838617677e9483bdb268d4b7 100644
--- a/DLCM-Model/src/main/resources/xslt/dlcm4migration-3.1-4.0.xsl
+++ b/DLCM-Model/src/main/resources/xslt/dlcm4migration-3.1-4.0.xsl
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xmlns:mets="http://www.loc.gov/METS/" xmlns:datacite="http://datacite.org/schema/kernel-4" xmlns:premis="http://www.loc.gov/premis/v3"
-	xmlns:dlcm2="http://www.dlcm.ch/dlcm/v2" xmlns:dlcm="http://www.dlcm.ch/dlcm/v3" xmlns:fits="http://hul.harvard.edu/ois/xml/ns/fits/fits_output" exclude-result-prefixes="">
+	xmlns:dlcm2="http://www.dlcm.ch/dlcm/v2" xmlns:dlcm="http://www.dlcm.ch/dlcm/v3" xmlns:fits="http://hul.harvard.edu/ois/xml/ns/fits/fits_output" 
+	exclude-result-prefixes="dlcm2">
 
 	<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="UTF-8" />
 
@@ -52,17 +53,16 @@
 
 	<!-- Migrate METS Profile -->
 	<xsl:template match="mets:mets/@PROFILE">
-		<xsl:attribute name="PROFILE"><xsl:text>dlcm_profile-4.0.xml</xsl:text></xsl:attribute>
-	</xsl:template>
-
-	<!-- Migrate METS xmlns:dlcm -->
-	<xsl:template match="mets:mets/@dlcm">
-		<xsl:attribute name="dlcm">http://www.dlcm.ch/dlcm/v3</xsl:attribute>
+		<xsl:attribute name="PROFILE">
+			<xsl:text>dlcm_profile-4.0.xml</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 	<!-- Migrate METS MDTYPEVERSION -->
 	<xsl:template match="mets:mets/mets:dmdSec/mets:mdWrap/@MDTYPEVERSION">
-		<xsl:attribute name="MDTYPEVERSION"><xsl:text>DataCite Metadata Schema 4.5 (dlcm_datacite-4.0.xsd)</xsl:text></xsl:attribute>
+		<xsl:attribute name="MDTYPEVERSION">
+			<xsl:text>DataCite Metadata Schema 4.5 (dlcm_datacite-4.0.xsd)</xsl:text>
+		</xsl:attribute>
 	</xsl:template>
 
 </xsl:stylesheet>
diff --git a/DLCM-PreservationPlanning/src/main/java/ch/dlcm/job/ComplianceLevelUpdateJob.java b/DLCM-PreservationPlanning/src/main/java/ch/dlcm/job/ComplianceLevelUpdateJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7bd530e69800e13c48f0eff81886854c95fa09b
--- /dev/null
+++ b/DLCM-PreservationPlanning/src/main/java/ch/dlcm/job/ComplianceLevelUpdateJob.java
@@ -0,0 +1,92 @@
+/*-
+ * %%----------------------------------------------------------------------------------------------
+ * DLCM Technology - DLCM Preservation Planning - ComplianceLevelUpdateJob.java
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * %----------------------------------------------------------------------------------------------%
+ * Copyright (C) 2017 - 2022 University of Geneva
+ * %----------------------------------------------------------------------------------------------%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>.
+ * ----------------------------------------------------------------------------------------------%%
+ */
+
+package ch.dlcm.job;
+
+import org.springframework.data.domain.Pageable;
+
+import ch.unige.solidify.rest.RestCollection;
+import ch.unige.solidify.rest.Result;
+import ch.unige.solidify.service.MessageService;
+
+import ch.dlcm.config.DLCMProperties;
+import ch.dlcm.model.PackageStatus;
+import ch.dlcm.model.oais.ArchivalInfoPackage;
+import ch.dlcm.model.preservation.PreservationJob;
+import ch.dlcm.service.JobProcessingService;
+import ch.dlcm.service.rest.trusted.TrustedArchivalInfoPackageRemoteResourceService;
+
+public class ComplianceLevelUpdateJob extends AbstractJob {
+
+  private final TrustedArchivalInfoPackageRemoteResourceService aipRemoteResourceService;
+
+  private final String defaultStorageUrl;
+
+  public ComplianceLevelUpdateJob(
+          DLCMProperties dlcmProperties,
+          MessageService messageService,
+          JobProcessingService jobProcessingService,
+          TrustedArchivalInfoPackageRemoteResourceService aipRemoteResourceService) {
+    super(dlcmProperties, messageService, jobProcessingService);
+    this.aipRemoteResourceService = aipRemoteResourceService;
+    this.defaultStorageUrl = dlcmProperties.getDefaultArchivalStorageUrl();
+  }
+
+  @Override
+  protected void execute(PreservationJob job, String executionId) {
+    final long total = this.getTotal(this.defaultStorageUrl);
+    Pageable pageable = this.getPageRequest();
+    RestCollection<ArchivalInfoPackage> collection;
+    do {
+      // List AIPs
+      collection = this.aipRemoteResourceService.getAipList(this.defaultStorageUrl, pageable);
+      pageable = pageable.next();
+      for (final ArchivalInfoPackage aip : collection.getData()) {
+        try {
+          if (aip.getInfo().getStatus() == PackageStatus.COMPLETED) {
+            // Update compliance level
+            final Result aipResult = this.aipRemoteResourceService.updateComplianceLevel(this.defaultStorageUrl, aip.getResId());
+            job = this.logResult(aipResult, job, executionId, aip.getResId(), this.getAipPublicUrl(this.defaultStorageUrl, aip.getResId()));
+          } else {
+            job = this.addIgnoredItem(job, executionId, aip.getResId(),
+                    this.getAipPublicUrl(this.defaultStorageUrl, aip.getResId()),
+                    "Archive not ready for compliance level update");
+          }
+        } catch (final Exception e) {
+          job = this.addInErrorItem(job, executionId, aip.getResId(), this.getAipPublicUrl(this.defaultStorageUrl, aip.getResId()),
+                  e.getMessage());
+        }
+        // Save intermediate step by 10%
+        final long num = job.getLastExecution().getLastExecutionReport().getProcessedItems()
+                + job.getLastExecution().getLastExecutionReport().getIgnoredItems()
+                + job.getLastExecution().getLastExecutionReport().getInErrorItems();
+        job = this.jobProcessingService.saveStep(job, executionId, num, total);
+      }
+    } while (collection.getPage().hasNext());
+  }
+
+  private long getTotal(String storageUrl) {
+    final RestCollection<ArchivalInfoPackage> collection = this.aipRemoteResourceService.getAipList(storageUrl, this.getPageRequestForTotal());
+    return collection.getPage().getTotalItems();
+  }
+}
diff --git a/DLCM-PreservationPlanning/src/main/java/ch/dlcm/job/MetadataMigrationJob.java b/DLCM-PreservationPlanning/src/main/java/ch/dlcm/job/MetadataMigrationJob.java
index 6e4cb3bb17a54c1da0b03d955a569eabed4db830..dd25e0a98142191960b4d56858f4a8cadea36023 100644
--- a/DLCM-PreservationPlanning/src/main/java/ch/dlcm/job/MetadataMigrationJob.java
+++ b/DLCM-PreservationPlanning/src/main/java/ch/dlcm/job/MetadataMigrationJob.java
@@ -46,6 +46,7 @@ import ch.dlcm.service.rest.trusted.TrustedDepositRemoteResourceService;
 import ch.dlcm.service.rest.trusted.TrustedSubmissionInfoPackageRemoteResourceService;
 
 public class MetadataMigrationJob extends AbstractJob {
+
   private static final String ARCHIVE_NOT_UPGRADABLE = "Archive not upgradable because it is already in default version or the data are not cleaned";
 
   private final TrustedDepositRemoteResourceService depositRemoteResourceService;
@@ -94,7 +95,8 @@ public class MetadataMigrationJob extends AbstractJob {
             job = this.ignoreArchive(job, executionId, this.defaultStorageUrl, aip, sipList, depositList);
           }
         } catch (final Exception e) {
-          job = this.addInErrorItem(job, executionId, aip.getResId(), this.getAipPublicUrl(this.defaultStorageUrl, aip.getResId()), e.getMessage());
+          job = this.addInErrorItem(job, executionId, aip.getResId(), this.getAipPublicUrl(this.defaultStorageUrl, aip.getResId()),
+                  e.getMessage());
         }
         // Save intermediate step by 10%
         final long num = job.getLastExecution().getLastExecutionReport().getProcessedItems()
@@ -103,7 +105,6 @@ public class MetadataMigrationJob extends AbstractJob {
         job = this.jobProcessingService.saveStep(job, executionId, num, total);
       }
     } while (collection.getPage().hasNext());
-
   }
 
   private PreservationJob ignoreArchive(PreservationJob job, String executionId, String storageUrl, ArchivalInfoPackage aip,
diff --git a/DLCM-PreservationPlanning/src/main/java/ch/dlcm/service/JobService.java b/DLCM-PreservationPlanning/src/main/java/ch/dlcm/service/JobService.java
index 7b5e5b546ca12dc26c1808ed293103b1b8862f5e..582e3acd1304a10bdc4ea7c2dc8534576cc8b8a1 100644
--- a/DLCM-PreservationPlanning/src/main/java/ch/dlcm/service/JobService.java
+++ b/DLCM-PreservationPlanning/src/main/java/ch/dlcm/service/JobService.java
@@ -42,6 +42,7 @@ import ch.dlcm.job.ApplyAipActionJob;
 import ch.dlcm.job.CheckComplianceLevelJob;
 import ch.dlcm.job.CheckReplicationJob;
 import ch.dlcm.job.CleanSubmissionJob;
+import ch.dlcm.job.ComplianceLevelUpdateJob;
 import ch.dlcm.job.DisposalJob;
 import ch.dlcm.job.MetadataMigrationJob;
 import ch.dlcm.job.PreloadAipJob;
@@ -133,6 +134,8 @@ public class JobService extends DLCMService {
     AbstractJob jobProcess = switch (job.getJobType()) {
       case METADATA_MIGRATION -> new MetadataMigrationJob(this.dlcmProperties, this.messageService, this.jobProcessingService,
               this.depositRemoteResourceService, this.sipRemoteResourceService, this.aipRemoteResourceService);
+      case COMPLIANCE_LEVEL_UPDATE -> new ComplianceLevelUpdateJob(this.dlcmProperties, this.messageService, this.jobProcessingService,
+              this.aipRemoteResourceService);
       case RELOAD -> new ReloadAipJob(this.dlcmProperties, this.messageService, this.jobProcessingService, this.aipRemoteResourceService);
       case REPLICATION -> new ReplicationJob(this.dlcmProperties, this.messageService, this.jobProcessingService, this.replicationService,
               this.archiveMetadataRemoteResourceService);
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/business/ArchivalInfoPackageService.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/business/ArchivalInfoPackageService.java
index fb4bec4399cf0e4f17656afc64b703aa6210ce75..e9bf324aebd19106f94e500baccaf598576a15e9 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/business/ArchivalInfoPackageService.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/business/ArchivalInfoPackageService.java
@@ -147,7 +147,7 @@ public class ArchivalInfoPackageService extends InfoPackageService<ArchivalInfoP
       this.notificationService.createNotification(updaterUser, message, notificationType, organizationalUnit, aip.getResId());
     } else if (aip.getInfo().getStatus() == PackageStatus.COMPLETED
             && (!this.historyService.hasBeenCompleted(aip.getResId())
-            || this.historyService.hasBeenUpdatedSinceLastCompletedStatus(aip.getResId()))) {
+                    || this.historyService.hasBeenUpdatedSinceLastCompletedStatus(aip.getResId()))) {
       message = this.messageService.get(NOTIFICATION_ARCHIVE_COMPLETED, new Object[] { aip.getResId() });
       this.notificationService.createArchiveCompletedNotifications(aip, updaterUser, message, organizationalUnit);
     }
@@ -169,6 +169,7 @@ public class ArchivalInfoPackageService extends InfoPackageService<ArchivalInfoP
             || aip.getInfo().getStatus() == PackageStatus.UPDATING_RETENTION
             || aip.getInfo().getStatus() == PackageStatus.METADATA_EDITION_PENDING
             || aip.getInfo().getStatus() == PackageStatus.METADATA_UPGRADE_PENDING
+            || aip.getInfo().getStatus() == PackageStatus.COMPLIANCE_LEVEL_UPDATE_PENDING
             || aip.getInfo().getStatus() == PackageStatus.PACKAGE_REPLICATION_PENDING
             || aip.getInfo().getStatus() == PackageStatus.TOMBSTONE_REPLICATION_PENDING) {
       boolean isBigPackage = this.getSize(aip) > this.fileSizeLimit.toBytes();
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/business/InfoPackageService.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/business/InfoPackageService.java
index 2ff30e459fb39b4672cc973a935686e9f3a3e19c..420ad8ab4a6ca796bf2b323132428356058aacb5 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/business/InfoPackageService.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/business/InfoPackageService.java
@@ -102,6 +102,8 @@ public abstract class InfoPackageService<T extends Resource> extends CompositeRe
       return PackageStatus.TOMBSTONE_REPLICATION_PENDING;
     } else if (PackageStatus.isMetadataUpgradeProcess(statusBeforeError)) {
       return PackageStatus.METADATA_UPGRADE_PENDING;
+    } else if (PackageStatus.isComplianceUpdateProcess(statusBeforeError)) {
+      return PackageStatus.COMPLIANCE_LEVEL_UPDATE_PENDING;
     } else {
       return PackageStatus.IN_PREPARATION;
     }
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/MetadataService.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/MetadataService.java
index 27761b73df034bbbca71010b02360265fe4175b6..60d4729326b5632fb4d0cec0973a45ef05bcc285 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/MetadataService.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/MetadataService.java
@@ -33,16 +33,16 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
+import jakarta.xml.bind.JAXBContext;
+import jakarta.xml.bind.JAXBException;
+import jakarta.xml.bind.Marshaller;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.logging.LogLevel;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.stereotype.Service;
 
-import jakarta.xml.bind.JAXBContext;
-import jakarta.xml.bind.JAXBException;
-import jakarta.xml.bind.Marshaller;
-
 import ch.unige.solidify.SolidifyConstants;
 import ch.unige.solidify.exception.SolidifyCheckingException;
 import ch.unige.solidify.exception.SolidifyProcessingException;
@@ -97,6 +97,9 @@ import ch.dlcm.service.rest.trusted.TrustedDepositRemoteResourceService;
 
 @Service
 public class MetadataService extends DLCMService implements OAIMetadataService {
+
+  private static final Logger log = LoggerFactory.getLogger(MetadataService.class);
+
   private final String preingestTempLocation;
   private final DLCMProperties dlcmProperties;
   private final DLCMRepositoryDescription repositoryDescription;
@@ -113,9 +116,7 @@ public class MetadataService extends DLCMService implements OAIMetadataService {
   private final FallbackPreservationPolicyRemoteResourceService preservationPolicyRemoteService;
   private final FallbackArchiveTypeRemoteResourceService archiveTypeResourceService;
   private final FileFormatService fileFormatService;
-  private TrustedDepositRemoteResourceService depositRemoteService;
-
-  private static final Logger log = LoggerFactory.getLogger(MetadataService.class);
+  private final TrustedDepositRemoteResourceService depositRemoteService;
 
   public MetadataService(
           FallbackLanguageRemoteResourceService languageRemoteService,
@@ -436,6 +437,12 @@ public class MetadataService extends DLCMService implements OAIMetadataService {
     metadataGenerator.upgradeMetadata(aip, metadataFile);
   }
 
+  public int updateComplianceLevel(ArchivalInfoPackage aip, Path metadataFile) throws JAXBException, IOException {
+    // Get metadata generator for the version
+    final MetadataGenerator metadataGenerator = this.getMetadataGenerator(aip.getInfo().getMetadataVersion());
+    return metadataGenerator.updateCompliance(aip, metadataFile);
+  }
+
   // ** Disposal **
 
   public void updateMetadataForDisposal(ArchivalInfoPackage aip, Path metadataFile) throws JAXBException, IOException {
@@ -462,7 +469,7 @@ public class MetadataService extends DLCMService implements OAIMetadataService {
     } else {
       if (df.getStatus() != null
               && (df.getStatus().equals(DataFileStatus.CHECK_COMPLIANCE)
-              || df.getStatus().equals(DataFileStatus.CHECK_COMPLIANCE_CLEANED))) {
+                      || df.getStatus().equals(DataFileStatus.CHECK_COMPLIANCE_CLEANED))) {
         xsd = new ClassPathResource(SolidifyConstants.SCHEMA_HOME + "/" + version.getMetsSchema());
       } else {
         xsd = new ClassPathResource(SolidifyConstants.SCHEMA_HOME + "/" + version.getRepresentationInfoSchema());
@@ -478,8 +485,8 @@ public class MetadataService extends DLCMService implements OAIMetadataService {
     // Add FITS schema
     if (!(df instanceof DepositDataFile)
             || (df.getStatus() != null
-            && (df.getStatus().equals(DataFileStatus.CHECK_COMPLIANCE)
-            || df.getStatus().equals(DataFileStatus.CHECK_COMPLIANCE_CLEANED)))) {
+                    && (df.getStatus().equals(DataFileStatus.CHECK_COMPLIANCE)
+                            || df.getStatus().equals(DataFileStatus.CHECK_COMPLIANCE_CLEANED)))) {
       list.add(new ClassPathResource(SolidifyConstants.SCHEMA_HOME + "/fits_output.xsd").getURL());
     }
     return list;
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataGenerator.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataGenerator.java
index 86a5866fa11d76792c6affe17631a92aa9e65135..49fc69bdc352b5c2bbace4a8a60b186b204b0bfd 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataGenerator.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataGenerator.java
@@ -262,6 +262,8 @@ public abstract class MetadataGenerator {
 
   public abstract void upgradeMetadata(ArchivalInfoPackage aip, Path metadataFile) throws IOException, JAXBException;
 
+  public abstract int updateCompliance(ArchivalInfoPackage aip, Path metadataFile) throws IOException, JAXBException;
+
   public abstract Map<String, String> extractInfoFromMetadata(Path metadataFile) throws IOException, JAXBException;
 
   public abstract void extractDataciteMetadataFromFile(Path filePath, OutputStream outputStream) throws JAXBException, IOException;
@@ -667,6 +669,11 @@ public abstract class MetadataGenerator {
     if (status.equals(PackageStatus.UPGRADING_METADATA.toString())) {
       return "updating metadata";
     }
+    // Updating compliance level
+    if (status.equals(PackageStatus.UPDATING_COMPLIANCE_LEVEL.toString())) {
+      return "updating compliance level";
+    }
+
     return null;
   }
 
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion1.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion1.java
index 287412a52e8da996229ea269fcfe0b361dc05c3e..df0c67b8479cb5d4564341f5f51fbc5989211c9c 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion1.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion1.java
@@ -45,20 +45,21 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+
 import javax.xml.namespace.QName;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-
 import jakarta.xml.bind.JAXBContext;
 import jakarta.xml.bind.JAXBElement;
 import jakarta.xml.bind.JAXBException;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
 import ch.unige.solidify.OAIConstants;
 import ch.unige.solidify.SolidifyConstants;
 import ch.unige.solidify.exception.SolidifyCheckingException;
@@ -1844,9 +1845,10 @@ public class MetadataVersion1 extends MetadataGenerator {
       switch (df.getDataCategory()) {
         case Package -> {
           switch (df.getDataType()) {
-            case Metadata ->
+            case Metadata -> {
               // DLCM metadata
-                    mets.getDmdSec().setMdWrap(this.loadDescriptiveMetadata(df));
+              mets.getDmdSec().setMdWrap(this.loadDescriptiveMetadata(df));
+            }
             case CustomMetadata -> {
               // Custom Metadata
               this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.METADATA_ROOT, df, outputLocation);
@@ -1857,15 +1859,18 @@ public class MetadataVersion1 extends MetadataGenerator {
             default -> throw new SolidifyProcessingException("Wrong Data Type");
           }
         }
-        case Primary ->
+        case Primary -> {
           // Primary data (research data)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.RESEARCH_DATA_ROOT, df, outputLocation);
-        case Secondary ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.RESEARCH_DATA_ROOT, df, outputLocation);
+        }
+        case Secondary -> {
           // Secondary data (documentation)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.DOC_ROOT, df, outputLocation);
-        case Software ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.DOC_ROOT, df, outputLocation);
+        }
+        case Software -> {
           // Software
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.SOFTWARE_ROOT, df, outputLocation);
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.SOFTWARE_ROOT, df, outputLocation);
+        }
         default -> throw new SolidifyProcessingException("Wrong Data Category");
       }
       nbProcessedDataFiles++;
@@ -1964,6 +1969,13 @@ public class MetadataVersion1 extends MetadataGenerator {
     throw new UnsupportedOperationException("Not supported for this metadata version");
   }
 
+  @Override
+  public int updateCompliance(ArchivalInfoPackage aip, Path metadataFile) throws IOException, JAXBException {
+    // Not applicable for this version
+    return 0;
+
+  }
+
   private void updatePreservationPolicy(ArchivalInfoPackage aip, IntellectualEntity premisAip) {
     // Remove duplicate
     if (premisAip.getPreservationLevel().size() > 1) {
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion2.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion2.java
index 0f5b9f0b30963d2f926bc31e9b20f3cb69ee2f4b..3bc61b44995daea5ffaf3d8d9b4cc2a6249cc8ac 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion2.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion2.java
@@ -45,20 +45,21 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+
 import javax.xml.namespace.QName;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-
 import jakarta.xml.bind.JAXBContext;
 import jakarta.xml.bind.JAXBElement;
 import jakarta.xml.bind.JAXBException;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
 import ch.unige.solidify.OAIConstants;
 import ch.unige.solidify.SolidifyConstants;
 import ch.unige.solidify.exception.SolidifyCheckingException;
@@ -536,6 +537,12 @@ public class MetadataVersion2 extends MetadataGenerator {
     throw new UnsupportedOperationException("Not supported for this metadata version");
   }
 
+  @Override
+  public int updateCompliance(ArchivalInfoPackage aip, Path metadataFile) throws IOException, JAXBException {
+    // Not applicable for this version
+    return 0;
+  }
+
   @Override
   public Map<String, String> extractInfoFromMetadata(Path metadataFile) throws IOException, JAXBException {
     final Map<String, String> infoList = new HashMap<>();
@@ -1978,9 +1985,10 @@ public class MetadataVersion2 extends MetadataGenerator {
       switch (df.getDataCategory()) {
         case Package -> {
           switch (df.getDataType()) {
-            case Metadata ->
+            case Metadata -> {
               // DLCM metadata
-                    mets.getDmdSec().setMdWrap(this.loadDescriptiveMetadata(df));
+              mets.getDmdSec().setMdWrap(this.loadDescriptiveMetadata(df));
+            }
             case CustomMetadata -> {
               // Custom Metadata
               this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.METADATA_ROOT, df, outputLocation);
@@ -1991,18 +1999,22 @@ public class MetadataVersion2 extends MetadataGenerator {
             default -> throw new SolidifyProcessingException("Wrong Data Type");
           }
         }
-        case Primary ->
+        case Primary -> {
           // Primary data (research data)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.RESEARCH_DATA_ROOT, df, outputLocation);
-        case Secondary ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.RESEARCH_DATA_ROOT, df, outputLocation);
+        }
+        case Secondary -> {
           // Secondary data (documentation)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.DOC_ROOT, df, outputLocation);
-        case Software ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.DOC_ROOT, df, outputLocation);
+        }
+        case Software -> {
           // Software
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.SOFTWARE_ROOT, df, outputLocation);
-        case Internal ->
-          // Internal (preview files)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.INTERNAL_ROOT, df, outputLocation);
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.SOFTWARE_ROOT, df, outputLocation);
+        }
+        case Internal -> {
+          // Internal (metadata files)
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.INTERNAL_ROOT, df, outputLocation);
+        }
         default -> throw new SolidifyProcessingException("Wrong Data Category");
       }
       nbProcessedDataFiles++;
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion3.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion3.java
index ab5b2d1ddb2192d84816aee9644118964f4758bf..92236ec32bc84a5c4b3535d8318a09fa2bbb835d 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion3.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion3.java
@@ -44,20 +44,21 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+
 import javax.xml.namespace.QName;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-
 import jakarta.xml.bind.JAXBContext;
 import jakarta.xml.bind.JAXBElement;
 import jakarta.xml.bind.JAXBException;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
 import ch.unige.solidify.OAIConstants;
 import ch.unige.solidify.SolidifyConstants;
 import ch.unige.solidify.exception.SolidifyCheckingException;
@@ -551,6 +552,13 @@ public class MetadataVersion3 extends MetadataGenerator {
     throw new UnsupportedOperationException("Not supported for this metadata version");
   }
 
+  @Override
+  public int updateCompliance(ArchivalInfoPackage aip, Path metadataFile) throws IOException, JAXBException {
+    // Not applicable for this version
+    return 0;
+
+  }
+
   @Override
   public Map<String, String> extractInfoFromMetadata(Path metadataFile) throws IOException, JAXBException {
     final Map<String, String> infoList = new HashMap<>();
@@ -2280,9 +2288,10 @@ public class MetadataVersion3 extends MetadataGenerator {
       switch (df.getDataCategory()) {
         case Package -> {
           switch (df.getDataType()) {
-            case Metadata ->
+            case Metadata -> {
               // DLCM metadata
-                    mets.getDmdSec().setMdWrap(this.loadDescriptiveMetadata(df));
+              mets.getDmdSec().setMdWrap(this.loadDescriptiveMetadata(df));
+            }
             case CustomMetadata -> {
               // Custom Metadata
               this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.METADATA_ROOT, df, outputLocation);
@@ -2293,21 +2302,26 @@ public class MetadataVersion3 extends MetadataGenerator {
             default -> throw new SolidifyProcessingException("Wrong Data Type");
           }
         }
-        case Primary ->
+        case Primary -> {
           // Primary data (research data)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.RESEARCH_DATA_ROOT, df, outputLocation);
-        case Secondary ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.RESEARCH_DATA_ROOT, df, outputLocation);
+        }
+        case Secondary -> {
           // Secondary data (documentation)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.DOC_ROOT, df, outputLocation);
-        case Software ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.DOC_ROOT, df, outputLocation);
+        }
+        case Software -> {
           // Software
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.SOFTWARE_ROOT, df, outputLocation);
-        case Administrative ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.SOFTWARE_ROOT, df, outputLocation);
+        }
+        case Administrative -> {
           // Administrative data
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.ADMIN_DATA_ROOT, df, outputLocation);
-        case Internal ->
-          // Internal (preview files)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.INTERNAL_ROOT, df, outputLocation);
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.ADMIN_DATA_ROOT, df, outputLocation);
+        }
+        case Internal -> {
+          // Internal (metadata files)
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.INTERNAL_ROOT, df, outputLocation);
+        }
         default -> throw new SolidifyProcessingException("Wrong Data Category");
       }
       nbProcessedDataFiles++;
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion4.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion4.java
index 025528af9df59062e2c15015e8dcd13310d206bd..2e6f4c78b9a899e6cec02c275a69e311a97e473b 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion4.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/metadata/MetadataVersion4.java
@@ -50,20 +50,21 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+
 import javax.xml.namespace.QName;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-
 import jakarta.xml.bind.JAXBContext;
 import jakarta.xml.bind.JAXBElement;
 import jakarta.xml.bind.JAXBException;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
 import ch.unige.solidify.OAIConstants;
 import ch.unige.solidify.SolidifyConstants;
 import ch.unige.solidify.exception.SolidifyCheckingException;
@@ -217,7 +218,9 @@ public class MetadataVersion4 extends MetadataGenerator {
             archivePrivateMetadataResourceService,
             metadataTypeService, orgUnitResourceService, licenseRemoteResourceService, languageResourceService, personRemoteResourceService,
             preservationPolicyRemoteService, archiveTypeResourceService, fileFormatService, historyService, gitInfoProperties);
+
     this.depositRemoteService = depositRemoteService;
+
     // JAXB context
     try {
       this.jaxbContext = JAXBContext.newInstance(Mets.class, Resource.class, PremisComplexType.class, Fits.class);
@@ -568,7 +571,7 @@ public class MetadataVersion4 extends MetadataGenerator {
     // Load Mets metadata from file
     final Mets mets = this.loadMetadataFile(metadataFile);
     // Get Premis object
-    PremisComplexType premis = mets.getAmdSec().getDigiprovMD().getMdWrap().getXmlData().getPremis();
+    final PremisComplexType premis = mets.getAmdSec().getDigiprovMD().getMdWrap().getXmlData().getPremis();
     final IntellectualEntity premisAip = this.findObject(premis.getObject(), ResourceName.AIP);
     // add history event
     this.addHistoryEvents(ResourceName.AIP, aip.getResId(), premis.getEvent(), premisAip.getObjectIdentifier());
@@ -584,32 +587,75 @@ public class MetadataVersion4 extends MetadataGenerator {
     this.saveXmlInFile(mets, metadataFile.toString());
   }
 
-  private void updateComplianceLevel(PremisComplexType premis) throws JAXBException {
+  @Override
+  public int updateCompliance(ArchivalInfoPackage aip, Path metadataFile) throws IOException, JAXBException {
+    int count = 0;
+    // Load Mets metadata from file
+    final Mets mets = this.loadMetadataFile(metadataFile);
+    // Get Premis object
+    final PremisComplexType premis = mets.getAmdSec().getDigiprovMD().getMdWrap().getXmlData().getPremis();
+    // Update compliance level
+    if ((count = this.updateComplianceLevel(premis)) == 0) {
+      return count;
+    }
+    final IntellectualEntity premisAip = this.findObject(premis.getObject(), ResourceName.AIP);
+    // add history event
+    this.addHistoryEvents(ResourceName.AIP, aip.getResId(), premis.getEvent(), premisAip.getObjectIdentifier());
+    // Update PREMIS metadata checksum
+    this.updateChecksum(mets.getAmdSec().getDigiprovMD().getMdWrap());
+    // Update PREMIS objects for collection
+    if (aip.isCollection()) {
+      this.updatePremisObjectsForCollection(new MdWrapWrapper(mets.getAmdSec().getDigiprovMD().getMdWrap()), aip);
+    }
+    // Save in file
+    this.saveXmlInFile(mets, metadataFile.toString());
+    return count;
+  }
+
+  private int updateComplianceLevel(PremisComplexType premis) throws JAXBException {
+    int count = 0;
+    // Get deposit ID
     final IntellectualEntity premisDeposit = this.findObject(premis.getObject(), ResourceName.DEPOSIT);
+    // Create Deposit object
     final Deposit deposit = new Deposit();
     deposit.setResId(premisDeposit.getObjectIdentifier().get(0).getObjectIdentifierValue());
+    // For each data file
     for (ObjectComplexType objectComplexType : premis.getObject().stream().filter(PremisFile.class::isInstance).toList()) {
       final PremisFile premisFile = (PremisFile) objectComplexType;
       Optional<ObjectIdentifierComplexType> fileId = this.getPremisObjectIdentifier(premisFile, this.getPackageType(ResourceName.DATAFILE));
       if (fileId.isPresent()) {
+        // Create Deposit Data File object
         final DepositDataFile depositDataFile = new DepositDataFile();
+        // Data File ID
         depositDataFile.setResId(fileId.get().getObjectIdentifierValue());
+        // Data File deposit
         depositDataFile.setInfoPackage(deposit);
+        // Data File size
         depositDataFile.setFileSize(premisFile.getObjectCharacteristics().get(0).getSize());
+        // Get FITS & DLCM info
         final Optional<ExtensionComplexType> fitsExtension = this.getPremisObjectExtension(premisFile, Fits.class);
         final Optional<ExtensionComplexType> dlcmExtension = this.getPremisObjectExtension(premisFile, DlcmInfo.class);
         if (fitsExtension.isPresent() && dlcmExtension.isPresent()) {
           final Fits fitsInfo = (Fits) fitsExtension.get().getAny().get(0);
           final DlcmInfo dlcmInfo = (DlcmInfo) dlcmExtension.get().getAny().get(0);
+          // Data File File Format info (FITS)
           depositDataFile.getFileFormat().setDetails(this.getFitsInfo(fitsInfo));
-          dlcmInfo.setComplianceLevel(this.fileFormatService.assessComplianceLevel(depositDataFile.getResId(), depositDataFile).value());
+          final int originalComplianceLevel = dlcmInfo.getComplianceLevel();
+          final int newComplianceLevel = this.fileFormatService.assessComplianceLevel(depositDataFile.getResId(), depositDataFile).value();
+          // Change compliance level
+          if (newComplianceLevel != originalComplianceLevel) {
+            count++;
+            dlcmInfo.setComplianceLevel(newComplianceLevel);
+          }
           if (dlcmInfo.getDataClassification().getValue().equals("Unknown")) {
+            count++;
             final DepositDataFile df = this.depositRemoteService.getDepositDataFile(deposit.getResId(), depositDataFile.getResId());
             dlcmInfo.setDataClassification(this.createDataClassification(df));
           }
         }
       }
     }
+    return count;
   }
 
   private PremisComplexType addPremisInfoFromUpdatedFiles(Mets mets, PremisComplexType premis,
@@ -2585,9 +2631,10 @@ public class MetadataVersion4 extends MetadataGenerator {
       switch (df.getDataCategory()) {
         case Package -> {
           switch (df.getDataType()) {
-            case Metadata ->
+            case Metadata -> {
               // DLCM metadata
-                    mets.getDmdSec().setMdWrap(this.loadDescriptiveMetadata(df));
+              mets.getDmdSec().setMdWrap(this.loadDescriptiveMetadata(df));
+            }
             case CustomMetadata -> {
               // Custom Metadata
               this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.METADATA_ROOT, df, outputLocation);
@@ -2598,21 +2645,26 @@ public class MetadataVersion4 extends MetadataGenerator {
             default -> throw new SolidifyProcessingException("Wrong Data Type");
           }
         }
-        case Primary ->
+        case Primary -> {
           // Primary data (research data)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.RESEARCH_DATA_ROOT, df, outputLocation);
-        case Secondary ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.RESEARCH_DATA_ROOT, df, outputLocation);
+        }
+        case Secondary -> {
           // Secondary data (documentation)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.DOC_ROOT, df, outputLocation);
-        case Software ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.DOC_ROOT, df, outputLocation);
+        }
+        case Software -> {
           // Software
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.SOFTWARE_ROOT, df, outputLocation);
-        case Administrative ->
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.SOFTWARE_ROOT, df, outputLocation);
+        }
+        case Administrative -> {
           // Administrative data
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.ADMIN_DATA_ROOT, df, outputLocation);
-        case Internal ->
-          // Internal (preview files)
-                this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.INTERNAL_ROOT, df, outputLocation);
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.ADMIN_DATA_ROOT, df, outputLocation);
+        }
+        case Internal -> {
+          // Internal (metadata files)
+          this.loadFile(root, structMap.getDiv(), premis, DLCMConstants.INTERNAL_ROOT, df, outputLocation);
+        }
         default -> throw new SolidifyProcessingException("Wrong Data Category");
       }
       nbProcessedDataFiles++;
diff --git a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/rest/abstractservice/ArchivalInfoPackageRemoteResourceService.java b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/rest/abstractservice/ArchivalInfoPackageRemoteResourceService.java
index 29f8ebe1c1b15229aacc8924ba18b5fd1fe7fee1..014b0c164da1a13fbcf2207c2f01842c09da55e3 100644
--- a/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/rest/abstractservice/ArchivalInfoPackageRemoteResourceService.java
+++ b/DLCM-ResourceServerCommon/src/main/java/ch/dlcm/service/rest/abstractservice/ArchivalInfoPackageRemoteResourceService.java
@@ -303,6 +303,11 @@ public abstract class ArchivalInfoPackageRemoteResourceService extends RemoteRes
     return this.restClientService.postResourceAction(url);
   }
 
+  public Result updateComplianceLevel(String storageUrl, String aipId) {
+    String url = this.getArchivalStorageUrlWithId(storageUrl, aipId) + "/" + DLCMActionName.START_COMPLIANCE_LEVEL_UPDATE;
+    return this.restClientService.postResourceAction(url);
+  }
+
   public RestCollection<ArchivalInfoPackage> getAipList(String storageUrl, Pageable pageable) {
     String jsonString = this.restClientService.getResource(storageUrl + "/" + ResourceName.AIP, pageable);
     return new RestCollection<>(jsonString, ArchivalInfoPackage.class);