diff --git a/core/archipelago/src/api/rpc/package/async_lifecycle.rs b/core/archipelago/src/api/rpc/package/async_lifecycle.rs index 3c99a163..ada96e83 100644 --- a/core/archipelago/src/api/rpc/package/async_lifecycle.rs +++ b/core/archipelago/src/api/rpc/package/async_lifecycle.rs @@ -295,6 +295,12 @@ impl RpcHandler { .ok_or_else(|| anyhow::anyhow!("Missing package id"))? .to_string(); super::validation::validate_app_id(&package_id)?; + // Update is stop → pull → remove → recreate, i.e. a fresh start by + // another name: on a disk that shrank since install it would resume + // cuprate's unprunable sync unchecked. Same gate as install and + // start, run BEFORE the Updating flip so a refusal leaves the app + // cleanly in its previous state. + super::dependencies::check_cuprate_disk_compatibility(&package_id).await?; // Reject if already in a transitional lifecycle. { diff --git a/core/archipelago/src/api/rpc/package/runtime.rs b/core/archipelago/src/api/rpc/package/runtime.rs index 8e0c02a1..de627004 100644 --- a/core/archipelago/src/api/rpc/package/runtime.rs +++ b/core/archipelago/src/api/rpc/package/runtime.rs @@ -257,6 +257,11 @@ impl RpcHandler { .and_then(|v| v.as_str()) .ok_or_else(|| anyhow::anyhow!("Missing package id"))?; validate_app_id(package_id)?; + // Restart is stop + recreate, so on a disk that shrank below the cuprate + // minimum after install it resumes the doomed unprunable sync just like + // start would — same gate, same "fail before clearing user-stopped / + // flipping state" contract (see handle_package_start). + super::dependencies::check_cuprate_disk_compatibility(package_id).await?; let single_orchestrator_app = self.orchestrator.is_some() && uses_single_orchestrator_app(package_id);