A hands-on demo project for a workshop on Spec-Driven Development (SDD) with AI agents. The repository starts from a plain Spring Boot skeleton and grows — branch by branch — into a Spring Batch CSV importer with a Thymeleaf + Chart.js browse UI, with each branch demonstrating a different SDD workflow.
- Java 21, Spring Boot 4.x, Spring Batch 6.x
- MySQL via Testcontainers (no H2)
- Thymeleaf + Chart.js for the browse UI (added on the UI branches)
- Maven (
./mvnw)
Local infra:
docker compose up -d # MySQL (optional; Docker Compose support starter is included in pom.xml)
./mvnw spring-boot:run # run the app / batch job
./mvnw test # run tests (Testcontainers)The branches form a linear progression. Each is built on the previous one and adds a distinct stage of the SDD workflow.
main ──► spec ──► implementation ──┬──► implementation-webui (OpenSpec)
└──► implementation-ui-with-superpowers (Superpowers)
| Branch | Base | What it demonstrates |
|---|---|---|
main |
— | Bare Spring Boot scaffold + SDD skills/commands installed under .claude/ and .junie/. Contains the original spec/proposal.md. |
spec |
main |
Specification artifacts produced step-by-step via SDD commands (clarify, analyze, constrain, generate-plan). |
implementation |
spec |
Plan executed phase-by-phase: a Spring Batch job that imports temperature CSVs into MySQL. |
implementation-webui |
implementation |
Adds a browse UI using the OpenSpec plugin (/opsx:propose → /opsx:apply). |
implementation-ui-with-superpowers |
implementation |
Adds the same browse UI using the Superpowers plugin for Claude Code (brainstorm → design → plan → TDD). |
Initial commit. Provides:
- A Spring Boot 3 project with Testcontainers configured (
compose.yaml,TestcontainersConfiguration.java). - The starting feature proposal at
spec/proposal.md(import temperature CSVs into MySQL with Spring Batch). - SDD skill packs preinstalled under
.claude/skills/and.junie/skills/:01-clarify,02-analyze,03-constrain,04-validate,05-generate-plan, plus thespring-batch-6reference skill.
Use this branch as the starting point for the workshop.
Each commit is one SDD command run against spec/proposal.md, producing one artifact:
| Step | Command | Output | Commit |
|---|---|---|---|
| 1 | /clarify |
spec/requirements.md — surface ambiguities, lock requirements |
7ab053f |
| 2 | /analyze |
spec/acceptance_criteria.md — WHEN-THEN-SHALL behavioral specs |
13439de |
| 3 | /constrain |
spec/constraints.md — architecture, tech constraints, patterns |
4d57355 |
| 4 | /generate-plan |
spec/plan.yaml — phased execution plan with dependencies |
9088a28 |
| 5 | (manual) | AGENTS.md / CLAUDE.md — execution protocol for the agent |
865b148 |
End-of-branch state: /spec contains the full input package an implementation agent
needs to start coding without further clarification.
Built on spec. The agent processes spec/plan.yaml phase by phase, halting at each
checkpoint, and tracks progress in spec/status.md.
| Commit | Phase | Content |
|---|---|---|
29d08c6 |
Phase 1 | Foundation: Flyway migration, AppProperties, TemperatureReading record, base config + tests. |
80e9179 |
Phase 2 | CSV reading layer: FlatFileItemReader + MultiResourceItemReader. |
1312249 |
Phase 3 | Processing/writing layer + job summary logging. |
c1240bc |
Phase 4 | Job assembly with fault tolerance + FileArchivalTasklet for CSV archival. |
bc88e5a |
Phase 5 | Integration tests, validation hardening, CSV parsing fixes. |
cc5a030 / 9111626 |
Post | Migrate tests to Spring Batch 6.x APIs (JobOperatorTestUtils, startJob()). |
End-of-branch state: working batch job that imports CSVs into MySQL, deduplicates on
(name, datetime), reports inserts vs duplicates, and archives processed files.
Built on implementation. Demonstrates the OpenSpec workflow.
| Commit | Step |
|---|---|
269e4c3 |
openspec init — installs opsx:* commands and skills, scaffolds openspec/. |
c8e38e3 |
/opsx:propose "create a minimalistic web ui to browse the temperature data..." — generates proposal.md, design.md, tasks.md, and per-capability spec deltas under openspec/changes/add-temperature-web-ui/. |
d99dd4a |
/opsx:apply — implements the change: TemperatureReadingRepository, REST API, Thymeleaf page, static JS/CSS, integration tests. |
a99fce3 |
Fix: add RunIdIncrementer so the batch job can run repeatedly. |
End-of-branch state: a browse page at / driven by a JSON API, with Chart.js plotting
readings filtered by sensor name and date range.
Built on implementation. Builds the same UI through the Superpowers plugin
for Claude Code, exercising its brainstorming → design → plan → TDD discipline.
| Commit | Step |
|---|---|
16747e1 |
Install superpowers@claude-plugins-official, update permissions. |
6006ef4 |
Fix: RunIdIncrementer for re-runnable batch job. |
29a46d0 |
Design doc (docs/designs/2026-05-10-temperature-browse-ui-design.md) produced via the brainstorming skill. |
707a204 |
Implementation plan (docs/plans/2026-05-10-temperature-browse-ui.md) — bite-sized TDD tasks. |
1cd6a71 |
Add spring-web + thymeleaf starters. |
b5d5ae5 |
DTO records for the API response. |
3a0d33c |
ReadingsRepository.listSensors (TDD). |
8823e2f |
ReadingsRepository.findReadings with capped result logic (TDD). |
a2466df |
GET /api/sensors. |
1ba991a |
GET /api/readings happy path. |
5c78e93 |
Tests: zero-rows and capped responses. |
6b78e28 |
Map validation failures → 400 with error JSON. |
2a586e6 |
UiController + minimal index template. |
518c472 |
Full UI shell: sensor select, presets, chart canvas. |
443c625 |
Browser controller: sensor pick, presets, chart, banners. |
4bdb99f / 91315d7 |
Polish: drop dead code, constrain chart height. |
0e96915 |
Cleanup: remove unused CSV data, extend dev tooling. |
End-of-branch state: same user-visible feature as implementation-webui, reached
through a TDD-driven workflow with explicit design and plan docs in docs/.
- Start on
main, readspec/proposal.md. - Check out
specand walk through the four artifacts to see how a vague proposal becomes an executable plan. - Check out
implementationand replay the phase commits to see plan-driven coding. - Compare the two UI branches:
implementation-webui— declarative, spec-first via OpenSpec.implementation-ui-with-superpowers— iterative, TDD-first via Superpowers.
The two UI branches converge on the same feature, which makes them useful for contrasting the workflows side by side.
spec/ Specification artifacts (read-only during implementation)
requirements.md
acceptance_criteria.md
constraints.md
plan.yaml
status.md
src/ Implementation code
data/ CSV inputs / archive (batch job)
openspec/ OpenSpec changes + capability specs (UI branch only)
docs/designs, docs/plans Superpowers design + plan docs (Superpowers branch only)
.claude/, .junie/ SDD/OpenSpec/Superpowers skills + slash commands
compose.yaml MySQL for local dev
See CLAUDE.md / AGENTS.md for the agent execution protocol that the
implementation branch follows.