5.4 KiB
Redis Production Capability Foundation Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox syntax for tracking.
Goal: Replace the adapter-only cache seam with a framework-free semantic cache contract, safe physical key construction, and a versioned typed atomic-program foundation without claiming that a real Redis runtime or any R2 capability is complete.
Architecture: application-core owns provider-neutral cache outcomes and mutation intent.
adapter:outbound:cache-redis owns physical key construction, digesting, Lua resources, program
descriptors, and typed primitive facades. Existing legacy routing remains compatible while migration
is incremental. No Redis SDK, raw command, raw key, or Lua concept crosses into core.
Scope boundary: This batch implements Phase 0 and selected Phase 1 foundations. Spring Data Redis/Lettuce runtime, codec/envelope, real-service integration, topology, distributed rate limit, idempotency, lease, session, and R2/R3 evidence remain separate implementation phases.
Task 1: Add the provider-neutral cache contract
Files:
-
Create:
src/application-core/src/main/java/dev/caskeleton/application/cache/CacheRegionPort.java -
Create:
src/application-core/src/main/java/dev/caskeleton/application/cache/CacheLookup.java -
Create:
src/application-core/src/main/java/dev/caskeleton/application/cache/CacheRecordMetadata.java -
Create:
src/application-core/src/main/java/dev/caskeleton/application/cache/CacheRecordIntent.java -
Create:
src/application-core/src/main/java/dev/caskeleton/application/cache/CacheRecordOutcome.java -
Create:
src/application-core/src/main/java/dev/caskeleton/application/cache/CacheInvalidationOutcome.java -
Create:
src/application-core/src/main/java/dev/caskeleton/application/cache/AuthoritativeAbsence.java -
Test:
src/application-core/src/test/java/dev/caskeleton/application/cache/CacheRegionContractTest.java -
Write a failing test for hit/negative/miss/unavailable distinctions and immutable metadata.
-
Verify RED with
./gradlew :application-core:test --tests '*CacheRegionContractTest'. -
Implement only framework-free values and ports.
-
Verify GREEN.
Task 2: Add canonical Redis physical keys
Files:
-
Modify:
src/adapter/outbound/cache-redis/build.gradle -
Create:
src/adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/key/RedisKeyNamespace.java -
Create:
src/adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/key/RedisKeyBuilder.java -
Create:
src/adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/key/RedisKeyDigest.java -
Test:
src/adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/key/RedisKeyBuilderTest.java -
Write a failing test proving namespace isolation, one stable hash tag, bounded key bytes, and absence of raw sensitive resource identifiers.
-
Verify RED.
-
Implement SHA-256 for opaque IDs and HMAC-SHA-256 for sensitive scopes using defensive secret copies and length-prefixed component encoding.
-
Verify GREEN.
Task 3: Add a typed, versioned atomic-program catalog
Files:
-
Create:
src/adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/program/RedisProgramId.java -
Create:
src/adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/program/RedisProgramDescriptor.java -
Create:
src/adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/program/RedisProgramCatalog.java -
Create:
src/adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/program/RedisProgramExecutor.java -
Create:
src/adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/program/RedisAtomicPrimitives.java -
Create:
src/adapter/outbound/cache-redis/src/main/resources/redis/scripts/compare-and-delete-v1.lua -
Create:
src/adapter/outbound/cache-redis/src/main/resources/redis/scripts/compare-and-expire-v1.lua -
Create:
src/adapter/outbound/cache-redis/src/main/resources/redis/scripts/set-if-absent-with-ttl-v1.lua -
Test:
src/adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/program/RedisProgramCatalogTest.java -
Test:
src/adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/program/RedisAtomicPrimitivesTest.java -
Write failing catalog and facade tests.
-
Verify RED.
-
Implement exact resource digest, key/argument bounds, typed status mapping, and no generic application-facing execution surface.
-
Verify GREEN.
Task 4: Record exact readiness and verify
Files:
-
Modify:
src/adapter/outbound/cache-redis/README.md -
Modify:
src/adapter/outbound/cache-redis/CLAUDE.md -
Modify:
docs/superpowers/specs/2026-07-26-redis-production-capability-design.md -
Mark only contract/key/program foundation as implemented and all real runtime/capability promotion as unimplemented.
-
Run:
cd src
./gradlew :application-core:check :adapter:outbound:cache-redis:check --console=plain
./gradlew verifyCleanArchitectureDependencies --console=plain
- Do not claim Redis cache R1/R2 until a real standalone service lane and codec/runtime evidence exist.