94 lines
5.4 KiB
Markdown
94 lines
5.4 KiB
Markdown
# 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`
|
|
|
|
- [x] Write a failing test for hit/negative/miss/unavailable distinctions and immutable metadata.
|
|
- [x] Verify RED with `./gradlew :application-core:test --tests '*CacheRegionContractTest'`.
|
|
- [x] Implement only framework-free values and ports.
|
|
- [x] 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`
|
|
|
|
- [x] Write a failing test proving namespace isolation, one stable hash tag, bounded key bytes, and
|
|
absence of raw sensitive resource identifiers.
|
|
- [x] Verify RED.
|
|
- [x] Implement SHA-256 for opaque IDs and HMAC-SHA-256 for sensitive scopes using defensive secret
|
|
copies and length-prefixed component encoding.
|
|
- [x] 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`
|
|
|
|
- [x] Write failing catalog and facade tests.
|
|
- [x] Verify RED.
|
|
- [x] Implement exact resource digest, key/argument bounds, typed status mapping, and no generic
|
|
application-facing execution surface.
|
|
- [x] 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`
|
|
|
|
- [x] Mark only contract/key/program foundation as implemented and all real runtime/capability
|
|
promotion as unimplemented.
|
|
- [x] Run:
|
|
|
|
```bash
|
|
cd src
|
|
./gradlew :application-core:check :adapter:outbound:cache-redis:check --console=plain
|
|
./gradlew verifyCleanArchitectureDependencies --console=plain
|
|
```
|
|
|
|
- [x] Do not claim Redis cache R1/R2 until a real standalone service lane and codec/runtime evidence
|
|
exist.
|