Sub-scope 07 (objectstorage) qualification source sets — manifest and probes
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
generatedAt=2026-08-30T03:02:47+00:00
cwd=/shared/codebase/clean-architecture-backend-template/src

=== OWNED FILES ===
40858f581274cdc9a0ca5c748179d24261b26dd0 objectStorageAwsQualificationTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/AwsS3DirectTransferQualificationTest.java 24
ed5ca64050483df64c2ed9323a3689442b5105f1 objectStorageAwsQualificationTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/AwsS3ManagedCommonSubsetQualificationTest.java 27
843ff6cb1ca56f9c0aa983a19b8946aab439b20d objectStorageMinioContractTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioDirectTransferContractTest.java 25
f9852e21f73a70c2e72a15884f5bc3754e04a144 objectStorageMinioContractTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectContractTest.java 291
7a58f87e6179c11b2365c03b2cc48531d68825cb objectStorageMinioFaultTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioDirectTransferFaultTest.java 32
668cb4d072928aa0731dbb160b6845cc564f8f73 objectStorageMinioFaultTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectFaultTest.java 147

files: 6

=== 8.1 lane registration: strict, non-skipping, required classes ===
$ sed -n '12,16p;53,84p' adapter/outbound/objectstorage/build.gradle
strictTestLanes {
    sourceSet('objectStorageMinioContractTest') { compilesAgainst 'main', 'test' }
    sourceSet('objectStorageMinioFaultTest') { compilesAgainst 'main', 'test' }
    sourceSet('objectStorageAwsQualificationTest') { compilesAgainst 'main', 'test' }
}
def objectStorageMinioContractQualification = registerStrictQualificationTest(
        name: 'objectStorageMinioContractTest',
        sourceSet: sourceSets.objectStorageMinioContractTest,
        requiredClasses: [
                'dev.caskeleton.adapter.outbound.objectstorage.qualification.MinioDirectTransferContractTest',
                'dev.caskeleton.adapter.outbound.objectstorage.qualification.MinioManagedObjectContractTest'
        ],
        description: 'Runs the non-skipping exact-release MinIO managed object contract.')
objectStorageMinioContractQualification.configure {
    shouldRunAfter tasks.named('test')
}

def objectStorageMinioFaultQualification = registerStrictQualificationTest(
        name: 'objectStorageMinioFaultTest',
        sourceSet: sourceSets.objectStorageMinioFaultTest,
        requiredClasses: [
                'dev.caskeleton.adapter.outbound.objectstorage.qualification.MinioDirectTransferFaultTest',
                'dev.caskeleton.adapter.outbound.objectstorage.qualification.MinioManagedObjectFaultTest'
        ],
        description: 'Runs the non-skipping digest-pinned MinIO/Toxiproxy fault contract.')
objectStorageMinioFaultQualification.configure {
    shouldRunAfter objectStorageMinioContractQualification
}

registerStrictQualificationTest(
        name: 'objectStorageAwsQualificationTest',
        sourceSet: sourceSets.objectStorageAwsQualificationTest,
        requiredClasses: [
                'dev.caskeleton.adapter.outbound.objectstorage.qualification.AwsS3DirectTransferQualificationTest',
                'dev.caskeleton.adapter.outbound.objectstorage.qualification.AwsS3ManagedCommonSubsetQualificationTest'
        ],
        description: 'Runs only with explicit protected AWS sandbox authority and exact inputs.')
exit=0

=== 8.2 conditional sibling: which lanes actually call a provider ===
$ grep -c 'client\.' adapter/outbound/objectstorage/src/objectStorageMinioContractTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectContractTest.java adapter/outbound/objectstorage/src/objectStorageMinioFaultTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectFaultTest.java adapter/outbound/objectstorage/src/objectStorageMinioContractTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioDirectTransferContractTest.java adapter/outbound/objectstorage/src/objectStorageMinioFaultTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioDirectTransferFaultTest.java adapter/outbound/objectstorage/src/objectStorageAwsQualificationTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/AwsS3ManagedCommonSubsetQualificationTest.java adapter/outbound/objectstorage/src/objectStorageAwsQualificationTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/AwsS3DirectTransferQualificationTest.java
adapter/outbound/objectstorage/src/objectStorageMinioContractTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectContractTest.java:2
adapter/outbound/objectstorage/src/objectStorageMinioFaultTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectFaultTest.java:2
adapter/outbound/objectstorage/src/objectStorageMinioContractTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioDirectTransferContractTest.java:0
adapter/outbound/objectstorage/src/objectStorageMinioFaultTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioDirectTransferFaultTest.java:0
adapter/outbound/objectstorage/src/objectStorageAwsQualificationTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/AwsS3ManagedCommonSubsetQualificationTest.java:0
adapter/outbound/objectstorage/src/objectStorageAwsQualificationTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/AwsS3DirectTransferQualificationTest.java:0
exit=0

--- the AWS lane body in full ---
$ cat adapter/outbound/objectstorage/src/objectStorageAwsQualificationTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/AwsS3ManagedCommonSubsetQualificationTest.java
package dev.caskeleton.adapter.outbound.objectstorage.qualification;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Map;
import org.junit.jupiter.api.Test;

class AwsS3ManagedCommonSubsetQualificationTest {

  @Test
  void protectedLaneRequiresExplicitAuthorityAndExactSandboxInputs() {
    Map<String, String> environment = System.getenv();

    assertThat(environment.get("OBJECT_STORAGE_AWS_QUALIFICATION_ENABLED"))
        .as("protected AWS qualification authority")
        .isEqualTo("true");
    assertThat(environment.get("OBJECT_STORAGE_AWS_BUCKET"))
        .as("exact sandbox bucket")
        .isNotBlank();
    assertThat(environment.get("OBJECT_STORAGE_AWS_REGION"))
        .as("exact sandbox region")
        .isNotBlank();
    assertThat(environment.get("OBJECT_STORAGE_AWS_EXPECTED_OWNER"))
        .as("exact expected owner")
        .matches("[0-9]{12}");
  }
}
exit=0

=== 8.3 pinned identities: image digests must agree across lanes and evidence ===
$ grep -rn 'sha256:' adapter/outbound/objectstorage/src/objectStorageMinioContractTest adapter/outbound/objectstorage/src/objectStorageMinioFaultTest adapter/outbound/objectstorage/src/test/resources/object-storage/minio-provider-evidence.json
adapter/outbound/objectstorage/src/objectStorageMinioContractTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectContractTest.java:44:      "minio/minio@sha256:4c4a4876193f030c81f57aabb22bcb9a73462010eb61fcab66908e03e5484af8";
adapter/outbound/objectstorage/src/objectStorageMinioFaultTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectFaultTest.java:39:          "minio/minio@sha256:4c4a4876193f030c81f57aabb22bcb9a73462010eb61fcab66908e03e5484af8");
adapter/outbound/objectstorage/src/objectStorageMinioFaultTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectFaultTest.java:42:              "ghcr.io/shopify/toxiproxy@sha256:"
adapter/outbound/objectstorage/src/test/resources/object-storage/minio-provider-evidence.json:5:  "image": "minio/minio@sha256:4c4a4876193f030c81f57aabb22bcb9a73462010eb61fcab66908e03e5484af8",
adapter/outbound/objectstorage/src/test/resources/object-storage/minio-provider-evidence.json:6:  "toxiproxyImage": "ghcr.io/shopify/toxiproxy@sha256:9378ed52a28bc50edc1350f936f518f31fa95f0d15917d6eb40b8e376d1a214e",
exit=0

=== 8.4 what the live MinIO contract actually proves ===
$ grep -n 'ifNoneMatch\|ifMatch\|assertPreconditionFailed\|overwritten' adapter/outbound/objectstorage/src/objectStorageMinioContractTest/java/dev/caskeleton/adapter/outbound/objectstorage/qualification/MinioManagedObjectContractTest.java
112:                    .ifNoneMatch("*")
126:    var overwrittenDespiteCreateOnlyCondition =
132:                    .ifNoneMatch("*")
141:    assertThat(overwrittenDespiteCreateOnlyCondition.eTag()).isNotBlank();
162:                    .ifMatch(head.eTag())
177:                    .ifNoneMatch("*")
184:    var overwrittenControlCreate =
190:                    .ifNoneMatch("*")
195:    assertThat(overwrittenControlCreate.eTag()).isNotBlank();
196:    assertPreconditionFailed(
203:                        .ifMatch("\"definitely-stale-etag\"")
266:                    .ifNoneMatch("*")
270:    var overwritten =
276:    assertThat(overwritten.asByteArray()).containsExactly(content);
283:  private static void assertPreconditionFailed(
exit=0

$ cat adapter/outbound/objectstorage/src/test/resources/object-storage/minio-provider-evidence.json
{
  "schema": 1,
  "providerType": "s3-compatible-minio-community-release-2024-01-16t16-07-38z",
  "providerVersion": "release-2024-01-16t16-07-38z-sdk-2.30.0",
  "image": "minio/minio@sha256:4c4a4876193f030c81f57aabb22bcb9a73462010eb61fcab66908e03e5484af8",
  "toxiproxyImage": "ghcr.io/shopify/toxiproxy@sha256:9378ed52a28bc50edc1350f936f518f31fa95f0d15917d6eb40b8e376d1a214e",
  "profile": "managed-common",
  "status": "UNSUPPORTED",
  "excludedProfiles": [
    "managed-single-create-only",
    "conditional-control-create",
    "managed-multipart-create-only",
    "direct-single-create-only",
    "direct-multipart-create-only"
  ],
  "limitations": [
    "PutObject If-None-Match was accepted and overwrote an existing object",
    "stale PutObject If-Match returned HTTP 412 but create-if-absent control CAS is not safe",
    "CompleteMultipartUpload accepted If-None-Match despite a pre-existing target and overwrote it",
    "managed immutable create, conditional control creation, and multipart create-only are disabled",
    "local single-node container evidence only",
    "not AWS evidence",
    "not production TLS or deployment-topology evidence"
  ]
}
exit=0

$ grep -n 'MINIO_COMMUNITY_2024_01_16\|release-2024-01-16' adapter/outbound/objectstorage/src/main/java/dev/caskeleton/adapter/outbound/objectstorage/s3/S3ProviderType.java adapter/outbound/objectstorage/src/main/java/dev/caskeleton/adapter/outbound/objectstorage/s3/S3ProviderVersion.java
adapter/outbound/objectstorage/src/main/java/dev/caskeleton/adapter/outbound/objectstorage/s3/S3ProviderType.java:8:  MINIO_COMMUNITY_2024_01_16("s3-compatible-minio-community-release-2024-01-16t16-07-38z");
adapter/outbound/objectstorage/src/main/java/dev/caskeleton/adapter/outbound/objectstorage/s3/S3ProviderVersion.java:7:      S3ProviderType.MINIO_COMMUNITY_2024_01_16, "release-2024-01-16t16-07-38z-sdk-2.30.0");
exit=0

