use super::common::TestDatabase; use std::{ fs, os::unix::fs::PermissionsExt, path::PathBuf, sync::atomic::{AtomicU64, Ordering}, time::{Duration as StdDuration, SystemTime}, }; use crank_artifacts::{ ArtifactRef, ArtifactStore, ReconciliationMutation, ReconciliationPresence, ReconciliationRegistration, RegisteredArtifact, }; use crank_core::{Workspace, WorkspaceId, WorkspaceStatus}; use crank_registry::{ ArtifactClaimFinalization, ArtifactClaimFinalizeOutcome, ArtifactClaimOutcome, ArtifactClaimRecheckOutcome, ArtifactClaimToken, ArtifactSourceId, ArtifactSourceLifecycle, ArtifactSourceSensitivity, ClaimArtifactReconciliationRequest, ClaimExpiredArtifactReconciliationRequest, CreateArtifactSourceRequest, CreateWorkspaceRequest, DetachArtifactSourceRequest, ListArtifactSourcesQuery, RegistryError, }; use serde_json::json; use time::{OffsetDateTime, format_description::well_known::Rfc3339}; static NEXT_ROOT: AtomicU64 = AtomicU64::new(0); pub(super) struct TestRoot(pub(super) PathBuf); impl TestRoot { pub(super) fn new(name: &str) -> Self { let path = std::env::temp_dir().join(format!( "crank-registry-artifacts-{name}-{}-{}", std::process::id(), NEXT_ROOT.fetch_add(1, Ordering::Relaxed) )); fs::create_dir(&path).unwrap(); fs::set_permissions(&path, fs::Permissions::from_mode(0o700)).unwrap(); Self(path) } } impl Drop for TestRoot { fn drop(&mut self) { let _ = fs::set_permissions(&self.0, fs::Permissions::from_mode(0o700)); let _ = fs::remove_dir_all(&self.0); } } pub(super) fn timestamp(value: &str) -> OffsetDateTime { OffsetDateTime::parse(value, &Rfc3339).unwrap() } fn reconciliation_candidate_for( store: &ArtifactStore, artifact: &RegisteredArtifact, ) -> crank_artifacts::ReconciliationCandidate { let (_, candidates) = store.scan_reconciliation(None, 4096, 32).unwrap(); candidates .into_iter() .find(|candidate| { matches!( store.register_reconciliation(candidate, StdDuration::ZERO, SystemTime::now()), Ok(ReconciliationRegistration::Registered(found)) if found == *artifact ) }) .expect("registered reconciliation candidate") } async fn create_workspace(registry: &crank_registry::PostgresRegistry, id: &str) -> WorkspaceId { let workspace_id = WorkspaceId::new(id); let created_at = timestamp("2026-08-26T10:00:00Z"); registry .create_workspace(CreateWorkspaceRequest { workspace: &Workspace { id: workspace_id.clone(), slug: id.replace('_', "-"), display_name: id.to_owned(), status: WorkspaceStatus::Active, settings: json!({}), created_at, updated_at: created_at, }, }) .await .unwrap(); workspace_id } #[tokio::test] async fn source_relations_are_scoped_replayable_pageable_and_detachable() { let database = TestDatabase::new().await; let registry = database.registry().await; let workspace_a = create_workspace(®istry, "ws_artifacts_a").await; let workspace_b = create_workspace(®istry, "ws_artifacts_b").await; let root = TestRoot::new("relations"); let store = ArtifactStore::open(&root.0).unwrap(); let registered = store.put_registered(b"openapi: 3.1.0\n").unwrap(); let source_id = ArtifactSourceId::new("src_shared"); let created_at = timestamp("2026-08-26T10:01:00Z"); let created = registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &source_id, artifact: ®istered, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Internal, created_at, }) .await .unwrap(); let replayed = registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &source_id, artifact: ®istered, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Internal, created_at: timestamp("2026-08-26T10:02:00Z"), }) .await .unwrap(); assert_eq!(replayed, created); assert!(matches!( registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &source_id, artifact: ®istered, mime_type: "application/json", sensitivity: ArtifactSourceSensitivity::Internal, created_at, }) .await, Err(RegistryError::SourceConflict { .. }) )); assert!(matches!( registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &source_id, artifact: ®istered, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Secret, created_at, }) .await, Err(RegistryError::SourceConflict { .. }) )); let different = store.put_registered(b"openapi: 3.0.3\n").unwrap(); assert!(matches!( registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &source_id, artifact: &different, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Internal, created_at, }) .await, Err(RegistryError::SourceConflict { .. }) )); assert!(matches!( registry.get_artifact_source(&workspace_b, &source_id).await, Err(RegistryError::SourceNotFound { .. }) )); let shared_in_b = registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_b, source_id: &source_id, artifact: ®istered, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Secret, created_at, }) .await .unwrap(); assert_eq!(shared_in_b.blob.digest, created.blob.digest); assert_ne!(shared_in_b.sensitivity, created.sensitivity); let raw_pool = database.raw_pool().await; let blob_count = sqlx::query_scalar::<_, i64>("select count(*) from artifact_blobs where digest = $1") .bind(registered.artifact_ref().digest_hex()) .fetch_one(&raw_pool) .await .unwrap(); assert_eq!(blob_count, 1); let total_blob_count: i64 = sqlx::query_scalar("select count(*) from artifact_blobs") .fetch_one(&raw_pool) .await .unwrap(); assert_eq!( total_blob_count, 1, "conflicting replay must roll back blob metadata" ); for id in ["src_page_a", "src_page_b"] { registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &ArtifactSourceId::new(id), artifact: ®istered, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Public, created_at, }) .await .unwrap(); } let first = registry .list_artifact_sources(ListArtifactSourcesQuery { workspace_id: &workspace_a, cursor: None, limit: 2, }) .await .unwrap(); assert_eq!(first.items.len(), 2); let second = registry .list_artifact_sources(ListArtifactSourcesQuery { workspace_id: &workspace_a, cursor: first.next_cursor.as_ref(), limit: 2, }) .await .unwrap(); assert_eq!(second.items.len(), 1); assert!(second.next_cursor.is_none()); let listed_ids = first .items .iter() .chain(second.items.iter()) .map(|source| source.source_id.as_str()) .collect::>(); assert_eq!(listed_ids, vec!["src_page_a", "src_page_b", "src_shared"]); assert!( first .items .iter() .chain(second.items.iter()) .all(|source| source.workspace_id == workspace_a) ); assert!(matches!( registry .list_artifact_sources(ListArtifactSourcesQuery { workspace_id: &workspace_b, cursor: first.next_cursor.as_ref(), limit: 2, }) .await, Err(RegistryError::InvalidArtifactSource { field: "cursor" }) )); sqlx::query( "insert into artifact_sources (workspace_id, source_id, blob_digest, mime_type, sensitivity, lifecycle, created_at, updated_at) select $1, 'src_bulk_' || lpad(value::text, 3, '0'), $2, 'application/yaml', 'public', 'active', $3, $3 from generate_series(0, 100) as value", ) .bind(workspace_a.as_str()) .bind(registered.artifact_ref().digest_hex()) .bind(created_at) .execute(&raw_pool) .await .unwrap(); let capped = registry .list_artifact_sources(ListArtifactSourcesQuery { workspace_id: &workspace_a, cursor: None, limit: u32::MAX, }) .await .unwrap(); assert_eq!(capped.items.len(), 100); let tail = registry .list_artifact_sources(ListArtifactSourcesQuery { workspace_id: &workspace_a, cursor: capped.next_cursor.as_ref(), limit: u32::MAX, }) .await .unwrap(); assert_eq!(tail.items.len(), 4); assert!(tail.next_cursor.is_none()); let invalid_id = ArtifactSourceId::new(format!("src_{}", "x".repeat(129))); assert!(matches!( registry .get_artifact_source(&workspace_a, &invalid_id) .await, Err(RegistryError::InvalidArtifactSource { field: "source_id" }) )); assert!(matches!( registry .detach_artifact_source(DetachArtifactSourceRequest { workspace_id: &workspace_a, source_id: &invalid_id, expected_updated_at: None, detached_at: created_at, }) .await, Err(RegistryError::InvalidArtifactSource { field: "source_id" }) )); let detached_at = timestamp("2026-08-26T10:03:00Z"); let detached = registry .detach_artifact_source(DetachArtifactSourceRequest { workspace_id: &workspace_a, source_id: &source_id, expected_updated_at: Some(created.updated_at), detached_at, }) .await .unwrap(); assert_eq!(detached.lifecycle, ArtifactSourceLifecycle::Detached); let retry = registry .detach_artifact_source(DetachArtifactSourceRequest { workspace_id: &workspace_a, source_id: &source_id, expected_updated_at: Some(created.updated_at), detached_at, }) .await .unwrap(); assert_eq!(retry, detached); assert!(matches!( registry .detach_artifact_source(DetachArtifactSourceRequest { workspace_id: &workspace_a, source_id: &source_id, expected_updated_at: Some(created.updated_at), detached_at: timestamp("2026-08-26T10:04:00Z"), }) .await, Err(RegistryError::SourceConflict { .. }) )); assert_eq!( registry .get_artifact_source(&workspace_a, &source_id) .await .unwrap() .lifecycle, ArtifactSourceLifecycle::Detached ); assert!(matches!( registry .read_artifact_source(&store, &workspace_a, &source_id) .await, Err(RegistryError::SourceUnavailable) )); assert_eq!( store.read(registered.artifact_ref()).unwrap(), b"openapi: 3.1.0\n" ); let concurrent_id = ArtifactSourceId::new("src_concurrent"); let concurrent = registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &concurrent_id, artifact: ®istered, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Internal, created_at, }) .await .unwrap(); let first_registry = registry.clone(); let second_registry = registry.clone(); let first_workspace = workspace_a.clone(); let second_workspace = workspace_a.clone(); let first_id = concurrent_id.clone(); let second_id = concurrent_id.clone(); let (first_detach, second_detach) = tokio::join!( async move { first_registry .detach_artifact_source(DetachArtifactSourceRequest { workspace_id: &first_workspace, source_id: &first_id, expected_updated_at: Some(concurrent.updated_at), detached_at: timestamp("2026-08-26T10:05:00Z"), }) .await }, async move { second_registry .detach_artifact_source(DetachArtifactSourceRequest { workspace_id: &second_workspace, source_id: &second_id, expected_updated_at: Some(concurrent.updated_at), detached_at: timestamp("2026-08-26T10:06:00Z"), }) .await } ); assert_eq!( usize::from(first_detach.is_ok()) + usize::from(second_detach.is_ok()), 1 ); assert_eq!( usize::from(matches!( first_detach, Err(RegistryError::SourceConflict { .. }) )) + usize::from(matches!( second_detach, Err(RegistryError::SourceConflict { .. }) )), 1 ); database.cleanup().await; } #[tokio::test] async fn verified_read_returns_only_digest_and_size_verified_bytes() { let database = TestDatabase::new().await; let registry = database.registry().await; let workspace_id = create_workspace(®istry, "ws_verified_read").await; let root = TestRoot::new("verified-read"); let store = ArtifactStore::open(&root.0).unwrap(); let bytes = b"openapi: 3.1.0\ninfo: {}\n"; let registered = store.put_registered(bytes).unwrap(); let valid_id = ArtifactSourceId::new("src_valid"); registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_id, source_id: &valid_id, artifact: ®istered, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Secret, created_at: timestamp("2026-08-26T11:00:00Z"), }) .await .unwrap(); let verified = registry .read_artifact_source(&store, &workspace_id, &valid_id) .await .unwrap(); assert_eq!(verified.bytes, bytes); let raw_pool = database.raw_pool().await; let missing_ref = ArtifactRef::from_digest_hex(&"f".repeat(64)).unwrap(); let missing_id = ArtifactSourceId::new("src_missing"); sqlx::query( "insert into artifact_blobs (digest, artifact_ref, size_bytes, storage_lifecycle, created_at, updated_at) values ($1, $2, 12, 'available', $3, $3)", ) .bind(missing_ref.digest_hex()) .bind(missing_ref.as_str()) .bind(timestamp("2026-08-26T11:01:00Z")) .execute(&raw_pool) .await .unwrap(); sqlx::query( "insert into artifact_sources (workspace_id, source_id, blob_digest, mime_type, sensitivity, lifecycle, created_at, updated_at) values ($1, $2, $3, 'application/yaml', 'internal', 'active', $4, $4)", ) .bind(workspace_id.as_str()) .bind(missing_id.as_str()) .bind(missing_ref.digest_hex()) .bind(timestamp("2026-08-26T11:01:00Z")) .execute(&raw_pool) .await .unwrap(); assert!(matches!( registry .read_artifact_source(&store, &workspace_id, &missing_id) .await, Err(RegistryError::SourceUnavailable) )); assert!( registry .get_artifact_source(&workspace_id, &missing_id) .await .is_ok() ); let wrong_size_id = ArtifactSourceId::new("src_wrong_size"); let wrong_size = store.put_registered(b"different source").unwrap(); registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_id, source_id: &wrong_size_id, artifact: &wrong_size, mime_type: "application/yaml", sensitivity: ArtifactSourceSensitivity::Internal, created_at: timestamp("2026-08-26T11:02:00Z"), }) .await .unwrap(); sqlx::query("update artifact_blobs set size_bytes = size_bytes + 1 where digest = $1") .bind(wrong_size.artifact_ref().digest_hex()) .execute(&raw_pool) .await .unwrap(); assert!(matches!( registry .read_artifact_source(&store, &workspace_id, &wrong_size_id) .await, Err(RegistryError::SourceIntegrity) )); let unavailable = store.put_registered(b"temporarily unavailable").unwrap(); let unavailable_id = ArtifactSourceId::new("src_unavailable"); registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_id, source_id: &unavailable_id, artifact: &unavailable, mime_type: "text/plain", sensitivity: ArtifactSourceSensitivity::Internal, created_at: timestamp("2026-08-26T11:03:00Z"), }) .await .unwrap(); sqlx::query("update artifact_blobs set storage_lifecycle = 'unavailable' where digest = $1") .bind(unavailable.artifact_ref().digest_hex()) .execute(&raw_pool) .await .unwrap(); assert!(matches!( registry .read_artifact_source(&store, &workspace_id, &unavailable_id) .await, Err(RegistryError::SourceUnavailable) )); let tampered = root .0 .join("sha256") .join(registered.artifact_ref().digest_hex().get(..2).unwrap()) .join(registered.artifact_ref().digest_hex()); fs::set_permissions(&tampered, fs::Permissions::from_mode(0o600)).unwrap(); fs::write(&tampered, vec![b'x'; bytes.len()]).unwrap(); assert!(matches!( registry .read_artifact_source(&store, &workspace_id, &valid_id) .await, Err(RegistryError::SourceIntegrity) )); assert!( registry .get_artifact_source(&workspace_id, &valid_id) .await .is_ok() ); database.cleanup().await; } #[tokio::test] async fn reconciliation_claims_are_fenced_global_and_allow_verified_revival() { let database = TestDatabase::new().await; let registry = database.registry().await; let raw_pool = database.raw_pool().await; let workspace_a = create_workspace(®istry, "ws_claim_a").await; let workspace_b = create_workspace(®istry, "ws_claim_b").await; let root = TestRoot::new("claims"); let store = ArtifactStore::open(&root.0).unwrap(); let unreferenced = store.put_registered(b"unreferenced\n").unwrap(); let started = timestamp("2026-08-27T10:00:00Z"); let lease = timestamp("2026-08-27T10:05:00Z"); let token = ArtifactClaimToken::generate(); assert_eq!(format!("{token:?}"), "ArtifactClaimToken(..)"); let request = ClaimArtifactReconciliationRequest { artifact: &unreferenced, token: token.clone(), claimed_at: started, lease_expires_at: lease, detached_grace: time::Duration::hours(24), }; assert_eq!( format!("{request:?}"), "ClaimArtifactReconciliationRequest(..)" ); let claim = match registry .claim_artifact_reconciliation(request) .await .unwrap() { ArtifactClaimOutcome::Claimed(claim) => claim, outcome => panic!("unexpected claim outcome: {outcome:?}"), }; assert_eq!(format!("{claim:?}"), "ArtifactReconciliationClaim(..)"); assert!(matches!( registry .claim_artifact_reconciliation(ClaimArtifactReconciliationRequest { artifact: &unreferenced, token, claimed_at: timestamp("2026-08-27T10:01:00Z"), lease_expires_at: lease, detached_grace: time::Duration::hours(24), }) .await .unwrap(), ArtifactClaimOutcome::Claimed(_) )); assert_eq!( registry .recheck_artifact_reconciliation_claim(&claim, started, time::Duration::hours(24)) .await .unwrap(), ArtifactClaimRecheckOutcome::Mutate ); assert!(matches!( registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &ArtifactSourceId::new("src_blocked"), artifact: &unreferenced, mime_type: "text/plain", sensitivity: ArtifactSourceSensitivity::Internal, created_at: started, }) .await, Err(RegistryError::ArtifactClaimInProgress) )); assert_eq!( registry .finalize_artifact_reconciliation_claim( &claim, ArtifactClaimFinalization::Quarantined, timestamp("2026-08-27T10:01:00Z"), ) .await .unwrap(), ArtifactClaimFinalizeOutcome::Retained ); let final_candidate = reconciliation_candidate_for(&store, &unreferenced); assert!(matches!( store.quarantine_reconciliation(final_candidate), Ok(ReconciliationMutation::Quarantined | ReconciliationMutation::AlreadyQuarantined) )); let quarantined_candidate = reconciliation_candidate_for(&store, &unreferenced); assert!(matches!( store.delete_quarantined_reconciliation(quarantined_candidate), Ok(ReconciliationMutation::Deleted | ReconciliationMutation::AlreadyAbsent) )); assert_eq!( store .reconciliation_presence(unreferenced.artifact_ref()) .unwrap(), ReconciliationPresence::Absent ); sqlx::query( "update artifact_blobs set claim_expires_at = clock_timestamp() - interval '1 second' where digest = $1", ) .bind(unreferenced.artifact_ref().digest_hex()) .execute(&raw_pool) .await .unwrap(); let recovery_now = registry.artifact_reconciliation_now().await.unwrap(); let probes = registry .list_expired_artifact_reconciliation_probes(recovery_now, 1) .await .unwrap(); assert_eq!( format!("{:?}", probes.first().expect("expired claim probe")), "ArtifactExpiredClaimProbe(..)" ); let winner = registry .claim_expired_artifact_reconciliation( probes.first().expect("expired claim probe"), ClaimExpiredArtifactReconciliationRequest { token: ArtifactClaimToken::generate(), claimed_at: recovery_now, lease_expires_at: recovery_now + time::Duration::minutes(5), }, ) .await .unwrap() .expect("expired claim was not recovered"); assert_eq!( registry .finalize_artifact_reconciliation_claim( &claim, ArtifactClaimFinalization::Deleted, timestamp("2026-08-27T10:05:01Z"), ) .await .unwrap(), ArtifactClaimFinalizeOutcome::Stale ); assert_eq!( registry .recover_artifact_reconciliation_claim( &winner, ArtifactClaimFinalization::AlreadyAbsent, timestamp("2026-08-27T10:05:02Z"), ) .await .unwrap(), ArtifactClaimFinalizeOutcome::Unavailable ); let republished = store.put_registered(b"unreferenced\n").unwrap(); let revived = registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_a, source_id: &ArtifactSourceId::new("src_revived"), artifact: &republished, mime_type: "text/plain", sensitivity: ArtifactSourceSensitivity::Internal, created_at: timestamp("2026-08-27T10:06:00Z"), }) .await .unwrap(); assert_eq!( revived.blob.lifecycle, crank_registry::ArtifactBlobLifecycle::Available ); let referenced = store.put_registered(b"referenced\n").unwrap(); let active_id = ArtifactSourceId::new("src_active"); let active = registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &workspace_b, source_id: &active_id, artifact: &referenced, mime_type: "text/plain", sensitivity: ArtifactSourceSensitivity::Internal, created_at: started, }) .await .unwrap(); assert!(matches!( registry .claim_artifact_reconciliation(ClaimArtifactReconciliationRequest { artifact: &referenced, token: ArtifactClaimToken::generate(), claimed_at: timestamp("2026-08-27T10:01:00Z"), lease_expires_at: lease, detached_grace: time::Duration::hours(24), }) .await .unwrap(), ArtifactClaimOutcome::ActiveReference )); registry .detach_artifact_source(DetachArtifactSourceRequest { workspace_id: &workspace_b, source_id: &active_id, expected_updated_at: Some(active.updated_at), detached_at: timestamp("2026-08-27T10:02:00Z"), }) .await .unwrap(); assert!(matches!( registry .claim_artifact_reconciliation(ClaimArtifactReconciliationRequest { artifact: &referenced, token: ArtifactClaimToken::generate(), claimed_at: timestamp("2026-08-27T10:03:00Z"), lease_expires_at: lease, detached_grace: time::Duration::hours(24), }) .await .unwrap(), ArtifactClaimOutcome::DetachedReferenceInGrace )); let concurrent = store.put_registered(b"concurrent claim\n").unwrap(); let first_registry = registry.clone(); let second_registry = registry.clone(); let first_artifact = concurrent.clone(); let second_artifact = concurrent.clone(); let (first, second) = tokio::join!( async move { first_registry .claim_artifact_reconciliation(ClaimArtifactReconciliationRequest { artifact: &first_artifact, token: ArtifactClaimToken::generate(), claimed_at: timestamp("2026-08-27T11:00:00Z"), lease_expires_at: timestamp("2026-08-27T11:05:00Z"), detached_grace: time::Duration::hours(24), }) .await }, async move { second_registry .claim_artifact_reconciliation(ClaimArtifactReconciliationRequest { artifact: &second_artifact, token: ArtifactClaimToken::generate(), claimed_at: timestamp("2026-08-27T11:00:00Z"), lease_expires_at: timestamp("2026-08-27T11:05:00Z"), detached_grace: time::Duration::hours(24), }) .await } ); let first = first.unwrap(); let second = second.unwrap(); assert_eq!( usize::from(matches!(first, ArtifactClaimOutcome::Claimed(_))) + usize::from(matches!(second, ArtifactClaimOutcome::Claimed(_))), 1 ); assert_eq!( usize::from(matches!(first, ArtifactClaimOutcome::HeldByOther)) + usize::from(matches!(second, ArtifactClaimOutcome::HeldByOther)), 1 ); let attach_race = store.put_registered(b"attach race\n").unwrap(); let claim_registry = registry.clone(); let attach_registry = registry.clone(); let claim_artifact = attach_race.clone(); let attach_artifact = attach_race.clone(); let attach_workspace = workspace_a.clone(); let (claim_race, attach_race) = tokio::join!( async move { claim_registry .claim_artifact_reconciliation(ClaimArtifactReconciliationRequest { artifact: &claim_artifact, token: ArtifactClaimToken::generate(), claimed_at: timestamp("2026-08-27T12:00:00Z"), lease_expires_at: timestamp("2026-08-27T12:05:00Z"), detached_grace: time::Duration::hours(24), }) .await }, async move { attach_registry .create_artifact_source(CreateArtifactSourceRequest { workspace_id: &attach_workspace, source_id: &ArtifactSourceId::new("src_attach_race"), artifact: &attach_artifact, mime_type: "text/plain", sensitivity: ArtifactSourceSensitivity::Internal, created_at: timestamp("2026-08-27T12:00:00Z"), }) .await } ); match (claim_race.unwrap(), attach_race) { (ArtifactClaimOutcome::ActiveReference, Ok(_)) => {} (ArtifactClaimOutcome::Claimed(_), Err(RegistryError::ArtifactClaimInProgress)) => {} (claim, attach) => panic!("unsafe claim/attach race outcome: {claim:?}, {attach:?}"), } database.cleanup().await; }