feat: add object storage production capability

This commit is contained in:
donghyeon-ka
2026-07-31 23:50:03 +09:00
parent b3add0162d
commit f0a6d1c8c8
427 changed files with 39930 additions and 699 deletions
@@ -0,0 +1,84 @@
# Object Storage Batch C Checkpoint
- Date: 2026-07-28
- Branch: `codex/objectstorage-production-capability`
- Worktree:
`/home/donghyeon/workspace/clean-architecture-backend-template-objectstorage`
- Evidence grade: repository-local tests plus digest-pinned single-node MinIO/Toxiproxy tests
- AWS execution: not authorized; source set compiled only
- Production-provider readiness advanced: no
## Implemented scope
- Added exact AWS S3 and MinIO provider bindings, bounded evidence descriptors, qualifier/error
mapping, secret references, endpoint/owner/addressing validation, and selected-only lifecycle
construction.
- Added bounded async request/response bridges and the managed S3 put, inspect, full/range download,
checksum, exact-version, cancellation, and content-length paths.
- Added canonical conditional S3 control storage and operation response-loss resolution. Provider
ETags remain adapter-private and are never exposed as logical versions.
- Added low-level managed multipart planning, sharded immutable part ledgers, initiate-before-I/O
state, explicit create/upload/list/complete/abort calls, and exact completion verification.
- Added non-skipping MinIO contract/fault lanes, an AWS compile-only qualification lane, a protected
workflow, and gate-matrix coverage.
The exact MinIO image is
`minio/minio@sha256:4c4a4876193f030c81f57aabb22bcb9a73462010eb61fcab66908e03e5484af8`.
The exact Toxiproxy image is
`ghcr.io/shopify/toxiproxy@sha256:9378ed52a28bc50edc1350f936f518f31fa95f0d15917d6eb40b8e376d1a214e`.
## Exact MinIO finding
Real-provider tests proved an asymmetric conditional profile:
- `PutObject If-None-Match: *` was accepted but overwrote an existing object.
- stale `PutObject If-Match` was rejected with HTTP 412.
- `CompleteMultipartUpload If-None-Match: *` was accepted and overwrote an existing object.
- checksum, HEAD, and range behavior passed the exercised contract.
Because immutable create and create-if-absent control CAS cannot be proven, the exact MinIO managed
and direct mutation profiles remain `UNSUPPORTED`. The implementation does not emulate missing
atomicity with HEAD followed by an unconditional write and does not promote a readiness card.
## TDD and verification
The task-focused RED runs first failed on the planned absent binding, bridge, conditional store,
multipart, and qualification types. Provider qualification then found the real MinIO conditional
behavior above; the descriptor and negative contract were changed instead of weakening the
contract.
Commands completed with `BUILD SUCCESSFUL`:
```bash
cd src
./gradlew :adapter:outbound:objectstorage:test \
--tests '*S3ProviderBindingTest' \
--tests '*S3ProviderQualifierTest' \
--tests '*S3ProviderCompositionTest' --console=plain
./gradlew :adapter:outbound:objectstorage:objectStorageMinioContractTest --console=plain
./gradlew :adapter:outbound:objectstorage:objectStorageMinioFaultTest --console=plain
./gradlew :adapter:outbound:objectstorage:objectStorageAwsQualificationTestClasses --console=plain
./gradlew :adapter:outbound:objectstorage:check --console=plain
./gradlew :adapter:outbound:objectstorage:verifyDependencyLocks \
verifyCleanArchitectureDependencies --console=plain
bash ../.github/scripts/verify-gate-matrix.sh
```
The gate matrix reports 22 gates: 21 verified and the protected AWS qualification gate explicitly
`delegated-pending`.
## LLM Wiki capture
The canonical vault `/home/donghyeon/workspace/ai-tool/llm-wiki-private/` and its parent
`/home/donghyeon/workspace/ai-tool/` do not exist in this environment. The required
`raw/branch-notes/codex-objectstorage-production-capability.md` and derived raw documents could not
be created or updated. No similarly named non-canonical clone was used.
## Remaining risks
- No AWS request was executed, so there is no observed AWS provider claim.
- The pinned MinIO topology is a local single-node container and is not production TLS,
multi-node, durability, or linearizability evidence.
- The detailed managed multipart fault matrix is not exhaustive enough for R2.
- No sample migration, public API, scan/publication choreography, retention, purge, or reaper is
included in this checkpoint.