Upload cleanup sounds simple until an encrypted workflow stages bytes before a record transition commits. Delete too early and a successful protected Memory loses media. Delete too late and abandoned ciphertext becomes permanent storage debris. The cleanup rule must know the difference.
Why encrypted uploads are staged
When a standard Memory changes to encrypted writing and files, the browser encrypts replacement file bytes and uploads them before Rails can atomically switch all of the record’s references. The database transition may reject a stale version, an unowned signed ID, or a malformed replacement.
Those checks are essential. They also create the possibility of a correctly uploaded blob that no committed Memory ever attaches.
Make the cleanup query describe one workflow
Inpages.me marks staging blobs from the protection transition and gives cleanup a bounded target: expired blobs from that workflow that are still unattached. It does not sweep every unattached Active Storage blob, because other upload paths can have different lifetimes and retry behavior.
The Rails guide documents attachment mechanics and cleanup tools, but application-specific staging rules still need an explicit contract. See the Active Storage overview for the framework boundary.
An attachment is evidence that the blob became real data
Before purging, the job checks whether an ActiveStorage::Attachment references the blob. A successful protection transition turns a staged blob into a keepsake or inline-image attachment; cleanup must then leave it alone, regardless of when it was initially uploaded.
Use expiry to separate abandoned work from slow work
A brief interruption, retry, or slow connection is not proof that an upload is abandoned. The cleanup policy waits until a defined expiry before considering an unattached protection blob eligible. The exact interval is a maintenance decision, not a user-facing encryption promise.
Run destructive cleanup out of the request path
A background job owns the purge operation and is covered by focused tests for expired and recent blobs. Keeping deletion out of a user save request reduces the chance that a temporary request error also becomes an irreversible cleanup action.
Operational delivery files use a similar lifecycle in short-lived export downloads, but the two cleanup scopes are intentionally separate.
Cleanup cannot repair a weak transition
The first defense is the all-or-nothing state transition: validate replacement blobs, update record references, and leave the original Memory intact on failure. Cleanup only removes the remaining abandoned artifacts. Read the atomic Memory encryption transition and encrypting files before Active Storage for the paths this job supports.