Sub-scope 07 (cache-redis) 의미 포트 어댑터 + live/topology test 기반 — manifest and probes revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5 generatedAt=2026-08-30T04:53:45+00:00 === OWNED FILES === 7767ce032226a698227c32afc9919a2f1505a6c9 main/java/dev/caskeleton/adapter/outbound/cache/redis/cache/CacheEnvelope.java 213 ba2e04b43e830b1e0e51a6d3f692b14453e48737 main/java/dev/caskeleton/adapter/outbound/cache/redis/cache/RedisCacheRegionAdapter.java 428 f3e259be5879a2e9779e8bdcdd7e3b8b26ffad66 main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency/IdempotencyScripts.java 306 7cfb0cd5d9627e6fbbcc8afdb8ff4fd860b2e0b5 main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency/RedisIdempotencyStoreAdapter.java 529 564bc94df42f434302237319ff5c5ebc251772ba main/java/dev/caskeleton/adapter/outbound/cache/redis/keyspace/CapabilityKeyspace.java 106 e95efcd322b8d0856c917fcbf5e8a87962b24bad main/java/dev/caskeleton/adapter/outbound/cache/redis/lease/LeaseScripts.java 203 e31bc74da675ccf4167175beb2130bc76d4686bc main/java/dev/caskeleton/adapter/outbound/cache/redis/lease/RedisDistributedLeaseAdapter.java 403 7ffbe5e790bf632073e1e74ba925947eca306d63 main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RateLimitKeys.java 49 dd5d94054767e33f9cf567f12c2c03f4827acd67 main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RateLimitScripts.java 280 b0721e10cd394ad39325d5240935e836859ffa19 main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RedisEdgeRateLimitAdapter.java 187 a0975e74004850c1b6a27999230ad3eacee92bb6 main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RealtimeKeys.java 81 dfac770123e102a33caa742a6a8a44fe5e67c9b9 main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RedisConnectionRegistryAdapter.java 301 ba584a26db38abe135f28b6b34d87ffc9095c489 main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RedisEphemeralFanoutAdapter.java 133 81e64fe800007dd0a5065a5a4952ecde8db8214d main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RegistrationCodec.java 76 b76c71e2c9eff216c24a9ba87c90c8433928f5c0 test/java/dev/caskeleton/adapter/outbound/cache/redis/cache/RedisCacheRegionAdapterTest.java 333 3d6f81aee563152b098ecf74119178a381b37cea test/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency/RedisIdempotencyStoreAdapterTest.java 337 ad8ef22e2b87d0afcdad7f0c654e7f5d9d7f911d test/java/dev/caskeleton/adapter/outbound/cache/redis/lease/RedisDistributedLeaseAdapterTest.java 292 04fc419bee78a203dee1a6a203a6baf3fd70b07e test/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RedisEdgeRateLimitAdapterTest.java 321 41e39a597eb22e44d44f1ab626cb7ba4e3ca925c test/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RedisConnectionRegistryAdapterTest.java 262 65fe3f6335d61e97fa4b145bdb4b549f0c26af8e test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/RedisSdkModuleBoundaryTest.java 237 073ebb2de3602c48907e06678529c156c7941fb0 test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/RedisSupportMatrixTest.java 193 5bb26b538cacf05a74c6dfe409f84d63b399b729 test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/RedisTopologyContractTest.java 306 1a04d38388906e8be77963dc6f719428dd90a043 test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/RedisTopologyEndpoint.java 244 2a4c054061162af30a8f4073d61759adde98126d test/java/dev/caskeleton/adapter/outbound/cache/redis/LiveRedisSemanticPortsTest.java 364 main: 14 === 8.1 의미 어댑터가 guard/executor/타입 API를 지나는가 === $ git grep -ln 'SyncRedisCommandExecutor\|ReactiveRedisCommandExecutor\|CommandPolicyGuard\|CommandRequest' -- 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/keyspace' exit=1 $ git grep -ln 'RedisValueOperations\|RedisHashOperations\|RedisOperations\|RedisKeyOperations' -- 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/keyspace' exit=1 --- 대신 무엇을 부르는가 --- $ git grep -c 'gateway()' -- 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache/RedisCacheRegionAdapter.java:6 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency/RedisIdempotencyStoreAdapter.java:6 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease/RedisDistributedLeaseAdapter.java:4 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RedisEdgeRateLimitAdapter.java:1 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RedisConnectionRegistryAdapter.java:13 exit=0 $ git grep -h '^import dev.caskeleton.adapter.outbound.cache.redis.sdk' -- 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/keyspace' | sed 's/.*sdk\.//' | sort | uniq -c | sort -rn 6 api.key.RedisNamespace; 5 lettuce.connection.RedisRuntimeOwner; 5 lettuce.connection.RedisLease; 5 lettuce.connection.RedisConnectionKind; 3 lettuce.operations.RedisCommandGateway; 1 lettuce.operations.ScoredMemberPage; 1 lettuce.operations.RedisPubSubGateway; 1 lettuce.operations.MemberScanPage; 1 lettuce.operations.HashScanPage; 1 api.operations.SortedSetAddOptions; 1 api.operations.ScoreRange; 1 api.operations.PageRequest; 1 api.operations.ExpirationCondition; 1 api.key.RedisKeyRules; 1 api.error.RedisOperationException; exit=0 === 8.1b gateway가 주장하는 전제 === $ sed -n '36,40p' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisCommandGateway.java *

The seam exists so the typed operations can be proven against a deterministic in-memory server * without Docker, and so the Lettuce types stay inside {@link LettuceRedisCommandGateway}. Policy, * permits, budgets, timeouts, and observability are not this interface's concern: everything routed * through it has already passed {@code CommandPolicyGuard}. */ exit=0 $ sed -n '24,26p' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/CommandPolicyGuard.java /** * The single admission point every command passes through. * exit=0 === 8.2 두 번째 키 렌더 경로 === $ grep -n 'requireRenderedSize\|MAX_KEY_BYTES' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/keyspace/CapabilityKeyspace.java exit=1 $ grep -n 'requireRenderedSize' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/api/key/RedisKeyRenderer.java 45: return RedisKeyRules.requireRenderedSize(rendered.toString(), maxKeyBytes); exit=0 $ git grep -ln 'CapabilityKeyspace' -- 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache/RedisCacheRegionAdapter.java adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency/RedisIdempotencyStoreAdapter.java adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/keyspace/CapabilityKeyspace.java adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease/RedisDistributedLeaseAdapter.java adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RateLimitKeys.java adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RealtimeKeys.java exit=0 === 8.3 README 대조: 이 어댑터들이 구현하는 application/shared port === $ git grep -h 'implements [A-Za-z<>, ]*Port' -- 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime' | sed 's/^ *//' public final class RedisCacheRegionAdapter implements CacheRegionPort { public final class RedisIdempotencyStoreAdapter implements IdempotencyStorePortV2 { public final class RedisDistributedLeaseAdapter implements DistributedLeasePort { public final class RedisEdgeRateLimitAdapter implements EdgeRateLimitPort { public final class RedisConnectionRegistryAdapter implements ConnectionRegistryPort { public final class RedisEphemeralFanoutAdapter implements EphemeralFanoutPort { exit=0 $ sed -n '25,28p;35,37p' adapter/outbound/cache-redis/README.md | Redis SDK typed API (`…cache.redis.sdk`) | 있음 | settings bind + validate 까지만 | 없음 | | Topology client / connection lifecycle | 없음 | 없음 | 없음 | | cache / session / idempotency / rate limit / lease semantic port | 없음 | 없음 | 없음 | | role-aware health·readiness contributor | 없음 | 없음 | 없음 | readiness registry에도 `selected` card가 없으므로 Redis R2 release claim은 없다. 아래 절들은 이전 세대 semantic adapter 세트의 설계 결정을 기록한 것이며, 그 코드는 현재 이 leaf에 없다. 복구 범위는 위 plan의 Phase E가 소유한다. exit=0 === 8.4 이 어댑터들의 test === $ git ls-files 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/cache' 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency' 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/lease' 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit' 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/realtime' | xargs -n1 basename RedisCacheRegionAdapterTest.java RedisIdempotencyStoreAdapterTest.java RedisDistributedLeaseAdapterTest.java RedisEdgeRateLimitAdapterTest.java RedisConnectionRegistryAdapterTest.java exit=0 $ git grep -h ' void [a-z]' -- 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/cache' 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency' 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/lease' 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit' 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/realtime' | sed 's/^ *//' | head -50 void recordThenLookup() { void staleButUsable() { void expiredIsAMiss() { void anAuthoritativeAbsenceIsNotAMiss() { void aFutureSchemaIsQuarantined() { void aForeignEntryIsReported() { void regionInvalidationBumpsTheGeneration() { void invalidateOneKey() { void onlyIfAbsentDoesNotOverwrite() { void onlyIfObservedRefusesAStaleWrite() { void onlyIfObservedAppliesWhenUnchanged() { void anUnreachableRedisDegrades() { void negativeEntriesExpireSooner() { void aFirstClaimExcludesTheSecond() { void theSameAttemptReplays() { void aDifferentRequestIsAMismatch() { void theHappyPathCompletesAndReplays() { void aStaleHandleCannotComplete() { void completingTwiceIsIdempotentOnlyForTheSameResult() { void aRetryableFailureAllowsAnotherAttempt() { void anAbandonedOperationRequiresRecovery() { void releasingBeforeExecutionFreesTheScope() { void releasingAfterStartIsRefused() { void anExpiredLeaseIsTakenOver() { void inspectionRecoversALostReply() { void anUnreachableRedisIsIndeterminate() { void anUncontendedAcquireSucceeds() { void aSecondHolderIsContended() { void theSameClaimReplays() { void theSameOwnerDifferentOperationConflicts() { void aNonHolderCannotRelease() { void aRenewExtendsOnlyOnConfirmation() { void anExpiredBudgetIsLost() { void releasingFreesTheLease() { void releasingTwiceIsAbsent() { void inspectingAnAbsentLease() { void anUnreachableRedisIsIndeterminate() { void ownerTokensAreUnguessable() { void aFixedWindowBoundsItsWindow() { void anewWindowRestoresTheBudget() { void aSlidingCounterIsHonestAboutBeingApproximate() { void aTokenBucketRefillsByPeriod() { void anUnreachableRedisFailsClosed() { void anUnknownPolicyIsIncompatible() { void anOversizedCostIsRefused() { void anExpiredCallerDeadlineIsRejectedImmediately() { void subjectsAreIsolated() { void announcedActorIsFound() { void multipleNodesAreReportedNewestFirst() { void reAnnounceReplaces() { exit=0