diff --git a/docs/superpowers/plans/2026-06-25-redis-stream-demo-implementation.md b/docs/superpowers/plans/2026-06-25-redis-stream-demo-implementation.md
new file mode 100644
index 0000000..7e8e620
--- /dev/null
+++ b/docs/superpowers/plans/2026-06-25-redis-stream-demo-implementation.md
@@ -0,0 +1,595 @@
+# Redis Stream Demo 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:** Build an independent Spring Boot demo project that imports `redis-stream-springboot-starter` and verifies real Redis Stream publish/subscribe behavior.
+
+**Architecture:** The demo is a downstream Maven Spring Boot application under `C:\code\hatch\redis-stream-starter-demo`. It depends on the starter from the local Maven repository, sends a `DemoMessage` with `RedisStreamEnhanceTemplate`, and consumes it with an `EnhanceStreamConsumerHandler` implementation. Integration testing uses the provided Redis service when reachable and skips when unreachable.
+
+**Tech Stack:** Java 8, Maven, Spring Boot `2.3.12.RELEASE`, JUnit 5, `redis-stream-springboot-starter:1.0.0-SNAPSHOT`, Redis Stream.
+
+---
+
+## File Structure
+
+- Create: `C:\code\hatch\redis-stream-starter-demo\pom.xml`
+ - Maven project definition, Spring Boot 2.3.12 dependency management, starter dependency, test setup.
+- Create: `C:\code\hatch\redis-stream-starter-demo\.gitignore`
+ - Keeps build output and IDE files out of the demo project.
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\resources\application.yml`
+ - Redis host/port defaults and overridable password environment variable.
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoApplication.java`
+ - Spring Boot entry point.
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoMessage.java`
+ - Demo message payload extending `StreamBaseMessage`.
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoRuntimeInbox.java`
+ - In-memory queue shared by runtime logging and integration tests.
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoProducer.java`
+ - Sends demo messages through the starter template.
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoConsumer.java`
+ - Starter consumer handler for `demo-topic`.
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoStartupRunner.java`
+ - Sends one demo message when running the app manually.
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\test\java\com\njcn\demo\redisstream\DemoRoundTripIntegrationTest.java`
+ - Real Redis publish/subscribe integration test.
+
+## Task 1: Prepare Build Scaffolding
+
+**Files:**
+- Create: `C:\code\hatch\redis-stream-starter-demo\pom.xml`
+- Create: `C:\code\hatch\redis-stream-starter-demo\.gitignore`
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\resources\application.yml`
+
+- [ ] **Step 1: Install the starter into the local Maven repository**
+
+Run from the starter repository:
+
+```bash
+mvn install
+```
+
+Expected: `BUILD SUCCESS`, with `redis-stream-springboot-starter-1.0.0-SNAPSHOT.jar` installed into the local Maven repository.
+
+- [ ] **Step 2: Create demo project directories**
+
+Run:
+
+```powershell
+New-Item -ItemType Directory -Force `
+ 'C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream', `
+ 'C:\code\hatch\redis-stream-starter-demo\src\main\resources', `
+ 'C:\code\hatch\redis-stream-starter-demo\src\test\java\com\njcn\demo\redisstream'
+```
+
+Expected: all three directories exist.
+
+- [ ] **Step 3: Create `pom.xml`**
+
+Write this exact content:
+
+```xml
+
+
+ 4.0.0
+
+ com.njcn.demo
+ redis-stream-starter-demo
+ 1.0.0-SNAPSHOT
+ jar
+
+ redis-stream-starter-demo
+ Demo application for redis-stream-springboot-starter
+
+
+ 1.8
+ 8
+ 8
+ UTF-8
+ UTF-8
+ 2.3.12.RELEASE
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+ com.njcn
+ redis-stream-springboot-starter
+ 1.0.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.2
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+
+```
+
+- [ ] **Step 4: Create `.gitignore`**
+
+Write this exact content:
+
+```gitignore
+target/
+.idea/
+*.iml
+.classpath
+.project
+.settings/
+```
+
+- [ ] **Step 5: Create `application.yml`**
+
+Write this exact content:
+
+```yaml
+spring:
+ redis:
+ host: ${DEMO_REDIS_HOST:192.168.1.22}
+ port: ${DEMO_REDIS_PORT:12379}
+ password: ${DEMO_REDIS_PASSWORD:}
+
+redis-stream:
+ env-isolation: true
+ env: demo
+ consumer-name: demo-consumer
+ read-count: 10
+ block-ms: 500
+ max-retry: 1
+```
+
+- [ ] **Step 6: Verify build scaffolding resolves dependencies**
+
+Run from the demo project:
+
+```bash
+mvn test -DskipTests
+```
+
+Expected: `BUILD SUCCESS`.
+
+## Task 2: Write the Round-Trip Integration Test First
+
+**Files:**
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\test\java\com\njcn\demo\redisstream\DemoRoundTripIntegrationTest.java`
+
+- [ ] **Step 1: Write the failing test**
+
+Write this exact content:
+
+```java
+package com.njcn.demo.redisstream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ConditionEvaluationResult;
+import org.junit.jupiter.api.extension.ExecutionCondition;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.redis.connection.stream.RecordId;
+
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+@ExtendWith(DemoRoundTripIntegrationTest.RedisReachableCondition.class)
+@SpringBootTest
+class DemoRoundTripIntegrationTest {
+
+ @Autowired
+ private DemoProducer producer;
+
+ @Autowired
+ private DemoRuntimeInbox inbox;
+
+ @Test
+ void publishesAndConsumesDemoMessage() throws Exception {
+ inbox.clear();
+ String payload = "integration-" + System.currentTimeMillis();
+
+ DemoMessage sent = new DemoMessage();
+ sent.setPayload(payload);
+ sent.setSource("integration-test");
+ sent.setTag("demo");
+
+ RecordId recordId = producer.send(sent);
+
+ DemoMessage received = inbox.poll(10, TimeUnit.SECONDS);
+ assertNotNull(recordId, "XADD should return a Redis stream record id");
+ assertNotNull(received, "consumer should receive the sent message within 10 seconds");
+ assertEquals(sent.getKey(), received.getKey(), "message key should round-trip");
+ assertEquals(payload, received.getPayload(), "payload should round-trip");
+ assertEquals("integration-test", received.getSource(), "source should round-trip");
+ }
+
+ static class RedisReachableCondition implements ExecutionCondition {
+ @Override
+ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
+ String host = System.getProperty("spring.redis.host",
+ System.getenv().getOrDefault("DEMO_REDIS_HOST", "192.168.1.22"));
+ int port = Integer.parseInt(System.getProperty("spring.redis.port",
+ System.getenv().getOrDefault("DEMO_REDIS_PORT", "12379")));
+ try (Socket socket = new Socket()) {
+ socket.connect(new InetSocketAddress(host, port), 500);
+ return ConditionEvaluationResult.enabled("redis reachable at " + host + ":" + port);
+ } catch (Exception e) {
+ return ConditionEvaluationResult.disabled("redis unreachable at " + host + ":" + port);
+ }
+ }
+ }
+}
+```
+
+- [ ] **Step 2: Run the test and verify it fails because application classes do not exist**
+
+Run from the demo project with the Redis password supplied through the process environment:
+
+```bash
+mvn test -Dtest=DemoRoundTripIntegrationTest
+```
+
+Expected: compilation failure mentioning missing symbols such as `DemoProducer`, `DemoRuntimeInbox`, and `DemoMessage`.
+
+## Task 3: Implement Minimal Demo Application Classes
+
+**Files:**
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoApplication.java`
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoMessage.java`
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoRuntimeInbox.java`
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoProducer.java`
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoConsumer.java`
+
+- [ ] **Step 1: Create `DemoApplication.java`**
+
+Write this exact content:
+
+```java
+package com.njcn.demo.redisstream;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class DemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(DemoApplication.class, args);
+ }
+}
+```
+
+- [ ] **Step 2: Create `DemoMessage.java`**
+
+Write this exact content:
+
+```java
+package com.njcn.demo.redisstream;
+
+import com.njcn.middle.stream.domain.StreamBaseMessage;
+
+public class DemoMessage extends StreamBaseMessage {
+
+ private String payload;
+
+ public String getPayload() {
+ return payload;
+ }
+
+ public void setPayload(String payload) {
+ this.payload = payload;
+ }
+}
+```
+
+- [ ] **Step 3: Create `DemoRuntimeInbox.java`**
+
+Write this exact content:
+
+```java
+package com.njcn.demo.redisstream;
+
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class DemoRuntimeInbox {
+
+ private final BlockingQueue messages = new LinkedBlockingQueue<>();
+
+ public void add(DemoMessage message) {
+ messages.add(message);
+ }
+
+ public DemoMessage poll(long timeout, TimeUnit unit) throws InterruptedException {
+ return messages.poll(timeout, unit);
+ }
+
+ public void clear() {
+ messages.clear();
+ }
+}
+```
+
+- [ ] **Step 4: Create `DemoProducer.java`**
+
+Write this exact content:
+
+```java
+package com.njcn.demo.redisstream;
+
+import com.njcn.middle.stream.template.RedisStreamEnhanceTemplate;
+import org.springframework.data.redis.connection.stream.RecordId;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DemoProducer {
+
+ public static final String TOPIC = "demo-topic";
+
+ private final RedisStreamEnhanceTemplate streamTemplate;
+
+ public DemoProducer(RedisStreamEnhanceTemplate streamTemplate) {
+ this.streamTemplate = streamTemplate;
+ }
+
+ public RecordId send(DemoMessage message) {
+ return streamTemplate.send(TOPIC, message, false);
+ }
+}
+```
+
+- [ ] **Step 5: Create `DemoConsumer.java`**
+
+Write this exact content:
+
+```java
+package com.njcn.demo.redisstream;
+
+import com.njcn.middle.stream.handler.EnhanceStreamConsumerHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DemoConsumer extends EnhanceStreamConsumerHandler {
+
+ public static final String GROUP = "demo-group";
+
+ private static final Logger log = LoggerFactory.getLogger(DemoConsumer.class);
+
+ private final DemoRuntimeInbox inbox;
+
+ public DemoConsumer(DemoRuntimeInbox inbox) {
+ this.inbox = inbox;
+ }
+
+ @Override
+ public String topic() {
+ return DemoProducer.TOPIC;
+ }
+
+ @Override
+ public String group() {
+ return GROUP;
+ }
+
+ @Override
+ public Class messageType() {
+ return DemoMessage.class;
+ }
+
+ @Override
+ public void handleMessage(DemoMessage message) {
+ log.info("Consumed Redis Stream demo message: key={}, payload={}, source={}, tag={}",
+ message.getKey(), message.getPayload(), message.getSource(), message.getTag());
+ inbox.add(message);
+ }
+
+ @Override
+ public boolean isRetry() {
+ return false;
+ }
+
+ @Override
+ public boolean throwException() {
+ return false;
+ }
+}
+```
+
+- [ ] **Step 6: Run the integration test and verify it passes**
+
+Run from the demo project with the Redis password supplied through the process environment:
+
+```bash
+mvn test -Dtest=DemoRoundTripIntegrationTest
+```
+
+Expected: `BUILD SUCCESS`, and the test reports one successful test when Redis is reachable.
+
+## Task 4: Add Manual Startup Publisher
+
+**Files:**
+- Create: `C:\code\hatch\redis-stream-starter-demo\src\main\java\com\njcn\demo\redisstream\DemoStartupRunner.java`
+
+- [ ] **Step 1: Write the failing startup-runner test by extending the integration test**
+
+Modify `DemoRoundTripIntegrationTest.java` to include this field and test method:
+
+```java
+ @Autowired
+ private DemoStartupRunner startupRunner;
+
+ @Test
+ void startupRunnerPublishesDemoMessage() throws Exception {
+ inbox.clear();
+
+ startupRunner.run();
+
+ DemoMessage received = inbox.poll(10, TimeUnit.SECONDS);
+ assertNotNull(received, "startup runner should publish a message");
+ assertEquals("startup-runner", received.getSource(), "startup runner should set source");
+ assertEquals("hello redis stream starter", received.getPayload(), "startup runner payload should match");
+ }
+```
+
+The full test class should still keep the first `publishesAndConsumesDemoMessage` test unchanged.
+
+- [ ] **Step 2: Run the test and verify it fails because `DemoStartupRunner` does not exist**
+
+Run:
+
+```bash
+mvn test -Dtest=DemoRoundTripIntegrationTest
+```
+
+Expected: compilation failure mentioning missing symbol `DemoStartupRunner`.
+
+- [ ] **Step 3: Create `DemoStartupRunner.java`**
+
+Write this exact content:
+
+```java
+package com.njcn.demo.redisstream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.data.redis.connection.stream.RecordId;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DemoStartupRunner implements ApplicationRunner {
+
+ private static final Logger log = LoggerFactory.getLogger(DemoStartupRunner.class);
+
+ private final DemoProducer producer;
+
+ public DemoStartupRunner(DemoProducer producer) {
+ this.producer = producer;
+ }
+
+ @Override
+ public void run(ApplicationArguments args) {
+ run();
+ }
+
+ public RecordId run() {
+ DemoMessage message = new DemoMessage();
+ message.setPayload("hello redis stream starter");
+ message.setSource("startup-runner");
+ message.setTag("demo");
+ RecordId recordId = producer.send(message);
+ log.info("Published Redis Stream demo message: recordId={}, key={}, payload={}",
+ recordId, message.getKey(), message.getPayload());
+ return recordId;
+ }
+}
+```
+
+- [ ] **Step 4: Run the integration test and verify both tests pass**
+
+Run:
+
+```bash
+mvn test -Dtest=DemoRoundTripIntegrationTest
+```
+
+Expected: `BUILD SUCCESS`, with two successful tests when Redis is reachable.
+
+## Task 5: Final Verification
+
+**Files:**
+- No new files.
+
+- [ ] **Step 1: Run the starter build**
+
+Run from the starter repository:
+
+```bash
+mvn install
+```
+
+Expected: `BUILD SUCCESS`.
+
+- [ ] **Step 2: Run all demo tests**
+
+Run from the demo project with the Redis password supplied through the process environment:
+
+```bash
+mvn test
+```
+
+Expected: `BUILD SUCCESS`.
+
+- [ ] **Step 3: Run the demo application**
+
+Run from the demo project with the Redis password supplied through the process environment:
+
+```bash
+mvn spring-boot:run
+```
+
+Expected: startup logs show a published Redis Stream message and a consumed Redis Stream message. Stop the process after the message is consumed.
+
+- [ ] **Step 4: Capture final file status**
+
+Run from the starter repository:
+
+```bash
+git status --short
+```
+
+Expected: only the implementation plan file is uncommitted unless execution commits it separately.
+
+## Self-Review
+
+- Spec coverage: Tasks cover local starter installation, independent demo project creation, Redis configuration, producer, consumer, startup publishing, integration testing, and manual runtime verification.
+- Placeholder scan: No TBD/TODO markers are used. Redis password is intentionally not written into this committed plan.
+- Type consistency: `DemoMessage`, `DemoProducer`, `DemoConsumer`, `DemoRuntimeInbox`, `DemoStartupRunner`, and `DemoRoundTripIntegrationTest` use matching package names and method signatures.