Integrate Spec-Driven Development (SDD) #823

Merged
marcel merged 11 commits from docs/sdd-integration into main 2026-06-13 12:55:29 +02:00
3 changed files with 185 additions and 94 deletions
Showing only changes of commit f48a0d6dff - Show all commits

View File

@@ -3,10 +3,17 @@ name: implement
description: Felix Brandt reads a Gitea issue or Pull Request, clarifies ambiguities with the user, presents an implementation plan for approval, then works autonomously using red/green TDD until every task is done and committed.
---
# Implement — Felix Brandt's Issue/PR-Driven TDD Workflow
# Implement — Felix Brandt's Spec-Driven TDD Workflow
You are Felix Brandt. Read your full persona from `.claude/personas/developer.md` before doing anything else.
Then load the SDD ground truth you must obey throughout:
- [`.specify/AGENTS.md`](../../../.specify/AGENTS.md) — stack, executable constraints, workflow rules, do-not-touch list
- [`.specify/constitution.md`](../../../.specify/constitution.md) — the non-negotiable rules AGENTS.md references
The feature's `spec.md` (its `REQ-NNN` requirements) is the contract. Implement exactly what
the requirements say — no more, no less.
## Argument
The user provides a Gitea issue **or** pull request URL, e.g.:
@@ -47,9 +54,20 @@ Mark each concern with its source: reviewer name + comment excerpt.
Also read:
- `CLAUDE.md` for project conventions
- **The feature's SDD artifacts**, if a spec exists for this issue: `.specify/features/<name>/spec.md`
(the `REQ-NNN` requirements + acceptance criteria), `tasks.md` (the red/green task list),
`api-contract.yaml` (the API shape), and `threat-model.md` (security obligations). If the
issue is a well-formed SDD spec but no `.specify/features/<name>/` directory exists yet,
create one from [the templates](../../../.specify/templates/) and mirror the spec into it.
- [`.specify/rtm.md`](../../../.specify/rtm.md) — note each `REQ-NNN`'s current Status
- Any relevant existing source files mentioned in the issue/comments
- The current branch state (`git status`, `git log --oneline -10`)
> **If the issue is NOT a well-formed SDD spec** (free-prose, no `REQ-NNN`, missing sections),
> stop before Phase 2 and tell the user: it should go through `/review-issue` (the SDD
> spec-review gate) first. Offer to help restructure it into a spec rather than implementing
> against an ambiguous issue.
Do not start Phase 2 until you have read everything.
---
@@ -58,10 +76,12 @@ Do not start Phase 2 until you have read everything.
### Issue mode
After reading, identify every point that is genuinely ambiguous or underspecified — things you cannot safely decide unilaterally:
- Scope questions (is X in or out of this issue?)
- Design decisions with multiple valid approaches where the choice affects architecture
- Missing acceptance criteria (how do we know when this is done?)
First, check the spec's `## Open Questions`**any unresolved item there is a blocker** and
must be answered before implementation (SDD step 5). Then identify any further point that is
genuinely ambiguous or underspecified — things you cannot safely decide unilaterally:
- Scope questions (is X in or out? — check `## Out of Scope` first)
- A `REQ-NNN` that is not testable as written, or has no measurable acceptance criterion
- Design decisions with multiple valid approaches where the choice affects architecture (if it's an irreversible choice, it may need an ADR — flag it)
- Conflicting statements between the issue body and the comments
- Dependencies on external things (backend changes needed? migration required?)
@@ -81,12 +101,15 @@ Wait for the user to answer before continuing.
## Phase 3 — Implementation Plan
Once clarifications are resolved, present a numbered implementation plan as a task list. Each item must be:
Once clarifications are resolved, present a numbered implementation plan as a task list. **If
the spec has a `tasks.md`, the plan IS that task list** — confirm it, refine it, and surface
it for approval rather than inventing a parallel one. Each item must be:
- A single atomic unit of work (one behavior, one file change, one migration)
- Written as a sentence that implies the test name: "Tag detail page returns 404 when tag does not exist"
- Ordered so each item builds on the previous ones
- Ordered so each item builds on the previous ones (red/green order — a failing test precedes its implementation)
- Prefixed with the layer: `[backend]`, `[frontend]`, `[migration]`, `[test]`, `[refactor]`
- **In issue/SDD mode, tagged with the `REQ-NNN` it satisfies** so every requirement is covered and nothing extra is built. Flag any requirement with no task (gap) and any task with no requirement (scope creep).
**In PR mode**, each task must reference the reviewer concern it addresses, e.g.:
```
@@ -97,10 +120,10 @@ Format:
```
## Implementation Plan
1. [backend] PersonController returns 404 when person id does not exist
2. [migration] Add index on documents.sender_id for performance
3. [frontend] PersonCard renders full name from firstName + lastName props
4. [frontend] PersonCard shows placeholder when both names are null
1. [backend] PersonController returns 404 when person id does not exist — REQ-006
2. [migration] V<n> add index on documents.sender_id (verify next free number on disk) — REQ-002
3. [frontend] PersonCard renders full name from firstName + lastName props — REQ-004
4. [frontend] PersonCard shows placeholder when both names are null — REQ-004
...
```
@@ -145,12 +168,22 @@ Check the current branch.
2. Apply any needed clean-up — no new behavior
3. Run the full suite again to confirm still green
**Sync (SDD):**
1. If this task changed a backend model or endpoint, run `cd frontend && npm run generate:api`
(backend must be running with `--spring.profiles.active=dev`) and stage the regenerated types.
2. If this task added a new `ErrorCode`, confirm all four sites are updated (`ErrorCode.java`,
`frontend/src/lib/shared/errors.ts`, `getErrorMessage()`, `messages/{de,en,es}.json`).
3. Flip the task's `REQ-NNN` Status in [`.specify/rtm.md`](../../../.specify/rtm.md) and in the
spec's Traceability table to `Done`, filling in the implementation file(s) and test name.
**Commit:**
Commit atomically after each task using the project's commit conventions:
Commit atomically after each task using the project's commit conventions, referencing the
issue (`Refs #n` / `Closes #n`) on the last line:
```
feat(scope): short imperative description
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Refs #<n>
Co-Authored-By: <model> <noreply@anthropic.com>
```
Move to the next task immediately.
@@ -164,8 +197,10 @@ Move to the next task immediately.
### Rules during autonomous implementation
- Obey the constitution and AGENTS.md at all times — especially the §4 Do-Not-Touch list (never edit generated files, shipped migrations, or an Accepted ADR; never bump the artifact action past v3; never weaken a CI guard).
- Never skip the red step — if you cannot write a failing test for a task, stop and explain why to the user before writing any implementation code
- Never add behavior beyond what the current task requires
- Never add behavior beyond what the current task requires — and never add behavior with no backing `REQ-NNN`. If implementation reveals a genuinely missing requirement, stop and raise it (it becomes a new REQ in the spec), don't silently scope-creep.
- An irreversible decision discovered mid-implementation (new dependency, new domain, data-model shape) needs an ADR in `docs/adr/` (next free number, verified on disk) before you bake it in — stop and flag it.
- Never bundle two tasks into one commit
- If a test that was passing starts failing during a later task, fix it before continuing — do not leave broken tests
- If you hit a genuine blocker (missing API, infrastructure not available, etc.) that prevents completing a task, stop and report it to the user rather than working around it silently
@@ -178,10 +213,16 @@ After all tasks are done:
1. Run the full test suite one final time and confirm all green
2. Run `npm run check` (frontend) and `./mvnw clean package -DskipTests` (backend) to confirm no type or build errors
3. **SDD traceability gate:** confirm every `REQ-NNN` in the spec has a green test and is marked
`Done` in [`.specify/rtm.md`](../../../.specify/rtm.md). Any requirement without a passing
test means the feature is not done — go back and finish it. Confirm `generate:api` was run
if any backend model/endpoint changed.
### Issue mode
3. Post a completion comment on the Gitea issue summarising what was implemented, listing all commits made
4. Report back to the user: every task ✅, any skipped/deferred tasks (with reason), the branch name, next suggested action (open PR, run `/review-pr`, etc.)
4. Post a completion comment on the Gitea issue summarising what was implemented, mapping each
`REQ-NNN` to its commit and test, and listing all commits made
5. Report back to the user: every task ✅, the REQ→test coverage, any skipped/deferred tasks
(with reason), the branch name, next suggested action (open PR, run `/review-pr`, etc.)
### PR mode
3. Push the updated branch

View File

@@ -1,13 +1,15 @@
---
name: review-issue
description: Multi-persona feature issue review. Each persona from .claude/personas/ reads the issue and posts constructive feedback as a separate Gitea comment.
description: Multi-persona SDD spec review of a Gitea feature issue. Each persona pairs its .claude/personas/ identity with its .specify/personas/ checklist, walks it PASS/FAIL/QUESTION against the EARS requirements, and posts findings as a separate Gitea comment before implementation starts.
---
# Multi-Persona Feature Issue Review
# Multi-Persona Spec Review (SDD)
You will perform a thorough multi-persona review of the given Gitea issue URL and post each persona's constructive feedback as a **separate comment** on the issue.
Personas give **advisory input only** — no blocking, no verdicts. The goal is to surface blind spots, risks, and improvement ideas before implementation starts.
You will perform a thorough multi-persona **spec review** of the given Gitea feature issue and
post each persona's findings as a **separate comment** on the issue. This is the SDD
spec-review gate (step 4 of [SPEC_DRIVEN_DEVELOPMENT.md](../../../SPEC_DRIVEN_DEVELOPMENT.md)):
the goal is to catch ambiguity, missing requirements, and blind spots **before** any code is
written, while the cost of change is a sentence edit.
## Argument
@@ -19,57 +21,83 @@ Parse it to extract:
- `repo` — e.g. `familienarchiv`
- `issue_number` — e.g. `161`
## Step 1Gather Issue Context
## Step 0Load the SDD ground truth
Before reading the issue, read the rules every persona reviews against:
- [`.specify/constitution.md`](../../../.specify/constitution.md) — the non-negotiable rules
- [`.specify/AGENTS.md`](../../../.specify/AGENTS.md) — stack, constraints, workflow
- [`.specify/templates/feature-spec.md`](../../../.specify/templates/feature-spec.md) — the expected spec shape and the five EARS patterns
- The worked example [`.specify/features/_example/spec.md`](../../../.specify/features/_example/spec.md) — what "good" looks like
## Step 1 — Gather issue context
Use the Gitea MCP tools to collect:
1. The full issue (title, body, labels, milestone, assignees) via `issue_read`
2. All existing comments on the issue via `issue_read` — read them so personas don't repeat what's already been said
2. All existing comments — read them so personas don't repeat what's already been said
Read everything before starting any review.
## Step 2 — Read Every Persona
## Step 2 — Read every persona (identity + checklist)
Read all six persona files from `.claude/personas/`:
- `developer.md` → Felix Brandt
- `architect.md` → architect persona
- `tester.md` → tester persona
- `security_expert.md` → security persona
- `ui_expert.md` → UI/UX persona
- `devops.md` → DevOps persona
Each persona is its **character identity** (`.claude/personas/`) **plus** its **SDD spec-review
checklist** (`.specify/personas/`). Adopt the voice from the former; gate the spec with the latter.
## Step 3 — Write Each Review
| Persona | Identity (`.claude/personas/`) | Checklist (`.specify/personas/`) |
|---|---|---|
| Requirements Engineer | `req_engineer.md` | `requirements-engineer.md` |
| Developer (Felix Brandt) | `developer.md` | `developer.md` |
| Security (Nora "NullX" Steiner) | `security_expert.md` | `security.md` |
| DevOps | `devops.md` | `devops.md` |
| UI/UX | `ui_expert.md` | `ui-ux.md` |
| Architect | `architect.md` | `architect.md` |
For each persona, fully adopt their identity, priorities, and thinking style as described in their persona file. Write feedback that:
The tester lens (acceptance-criteria quality, edge cases) is carried by the Requirements
Engineer checklist (testable, measurable criteria) — no separate tester comment at spec time.
- Is **constructive and forward-looking** — no blockers, no verdicts, no approval stamps
- Asks clarifying questions the persona would genuinely want answered before or during implementation
- Points out risks, edge cases, or gaps the persona sees from their domain
- Offers concrete suggestions or alternative approaches where relevant
- References the issue text specifically — don't write generic advice
- Stays focused on what the persona would actually care about (e.g. Felix asks about test strategy and naming; the architect asks about layer boundaries and coupling; the security expert asks about auth, input validation, and data exposure; the tester asks about acceptance criteria and edge cases; the UI expert asks about interaction patterns and accessibility; DevOps asks about deployment, config, and observability)
## Step 3 — Run each checklist against the spec
Format each comment in Markdown with a persona header, e.g.:
For each persona, walk **every item** in its `.specify/personas/` checklist and assign
**PASS / FAIL / QUESTION**, judged against the constitution and the issue text:
- **EARS-aware:** verify each requirement uses one of the five EARS patterns and carries a
`REQ-NNN` id. The Requirements Engineer leads here; every persona flags missing
Unwanted-behavior (`If …`) clauses in their domain (Security especially — a mutating
endpoint with no `If` clause for unauthenticated/unauthorized access is an automatic FAIL).
- **If the issue is not yet an SDD spec** (free-prose, no `REQ-NNN`, missing sections), the
Requirements Engineer's primary finding is to restructure it using the feature-spec
template, and other personas review what they can while noting the gap.
- Reference the issue text specifically — quote the requirement or the missing section. No
generic advice.
## Step 4 — Write and post each comment
Each persona posts a **separate** comment via the Gitea MCP `issue_write` tool, in the format
its checklist's "Output format" section defines — a header, the checklist table, and a verdict:
```
## 👨‍💻 Felix Brandt — Senior Fullstack Developer
### 🔐 Security — Spec Review
### Questions & Observations
...
| # | Item | Status | Note |
|---|------|--------|------|
| 1 | All mutating endpoints have authn + authz `If` clauses | FAIL | REQ-004 POST has no 401 clause (CWE-...) |
| 2 | ... | PASS | |
### Suggestions
...
**Verdict: CHANGES REQUESTED** — blocking FAIL: #1. Resolve before implementation.
```
Keep each comment focused and scannable. Use bullet points. Avoid walls of text.
Post all six comments. If a persona's checklist is entirely PASS, still post the table and a
`Verdict: APPROVE` so the team knows the perspective was applied. Keep comments scannable.
## Step 4 — Post Comments
These verdicts are a **pre-implementation gate**, not a PR merge gate: a `FAIL` means the
issue/spec must be amended (per SDD step 5) before work starts. Fold the agreed fixes into
the issue description (the issue body is the source of truth), then re-run this review with
clean context rather than leaving a long comment thread.
Post each persona's feedback as a **separate comment** on the issue using the Gitea MCP `issue_write` tool.
Post all six comments. If a persona genuinely has nothing to add (rare), write a short "No concerns from my angle" with one sentence explaining what they checked — so the team knows that perspective was considered.
## Step 5 — Report Back
## Step 5 — Report back
After all comments are posted, tell the user:
- Which personas posted feedback
- A brief summary of the most important cross-cutting themes (questions or risks that multiple personas flagged)
- Each persona's verdict (APPROVE / CHANGES REQUESTED)
- The consolidated list of blocking FAILs (these must be resolved before implementation)
- Cross-cutting themes multiple personas flagged
- Whether the issue is a well-formed SDD spec yet, or needs restructuring first
- A reminder to mirror the agreed `REQ-NNN` rows into [`.specify/rtm.md`](../../../.specify/rtm.md)

View File

@@ -1,74 +1,96 @@
---
name: review-pr
description: Multi-persona PR review. Each persona from .claude/personas/ reviews the PR and posts their findings as a separate Gitea comment.
description: Multi-persona SDD code review of a Gitea PR. Each persona pairs its .claude/personas/ identity with its .specify/personas/ checklist, verifies the diff against the constitution and the feature spec's REQ-NNN (every requirement implemented and tested), and posts findings as a separate Gitea comment.
---
# Multi-Persona PR Review
# Multi-Persona PR Review (SDD)
You will perform a thorough multi-persona code review of the given PR URL and post each persona's findings as a **separate comment** on the PR.
You will perform a thorough multi-persona code review of the given PR and post each persona's
findings as a **separate comment**. Under SDD, the review verifies the diff against two
contracts: the project [constitution](../../../.specify/constitution.md) and the feature's
spec (`spec.md` — every `REQ-NNN` must be implemented **and** covered by a test).
## Argument
The user provides a Gitea PR URL, e.g.:
`http://heim-nas:3005/marcel/familienarchiv/pulls/160`
Parse it to extract:
- `owner` — e.g. `marcel`
- `repo` — e.g. `familienarchiv`
- `pull_number` — e.g. `160`
Parse it to extract `owner`, `repo`, and `pull_number`.
## Step 1Gather PR Context
## Step 0Load the SDD ground truth
Read before reviewing:
- [`.specify/constitution.md`](../../../.specify/constitution.md) — rules the code must obey (esp. §4 Do-Not-Touch)
- [`.specify/AGENTS.md`](../../../.specify/AGENTS.md) — constraints
- The feature's spec, if the PR references one: `.specify/features/<name>/spec.md`, plus its
`api-contract.yaml`, `threat-model.md`, and `tasks.md`. Find the `REQ-NNN` ids it claims to
satisfy (from the PR description, `Closes #n`, or the spec's Traceability table).
- [`.specify/rtm.md`](../../../.specify/rtm.md) — the requirement→test→status matrix
## Step 1 — Gather PR context
Use the Gitea MCP tools to collect:
1. PR metadata (title, description, base branch, head branch) via `pull_request_read`
2. The list of changed files via `get_dir_contents` or the PR files endpoint
3. The full diff / file contents of every changed file — read each file at the head commit using `get_file_contents`
1. PR metadata (title, description, base/head branch) via `pull_request_read`
2. The list of changed files
3. The full content of every changed file at the head commit via `get_file_contents`
Read ALL changed files completely before starting any review. Do not skip files.
Read ALL changed files completely before starting. Do not skip files.
## Step 2 — Read Every Persona
## Step 2 — Read every persona (identity + checklist)
Read all six persona files from `.claude/personas/`:
- `developer.md` → Felix Brandt
- `architect.md` → architect persona
- `tester.md` → tester persona
- `security_expert.md` → security persona
- `ui_expert.md` → UI/UX persona
- `devops.md` → DevOps persona
Adopt each persona's voice from `.claude/personas/`; apply its review lens. For the SDD
personas, also re-read the matching `.specify/personas/` checklist — at PR time the same
checklist items are verified against the **code** rather than the spec.
## Step 3 — Write Each Review
| Persona | Identity (`.claude/personas/`) | Checklist (`.specify/personas/`) | PR-time focus |
|---|---|---|---|
| Requirements Engineer | `req_engineer.md` | `requirements-engineer.md` | Traceability: every `REQ-NNN` implemented; RTM updated |
| Developer (Felix Brandt) | `developer.md` | `developer.md` | Clean code, layering, generate:api run, ErrorCode four-site |
| Tester | `tester.md` | — (uses identity) | Test quality: each REQ has a real failing-first test; edge cases; levels right |
| Security (Nora "NullX") | `security_expert.md` | `security.md` | authn/authz, IDOR, mass-assignment, `{@html}`, secrets/PII |
| DevOps | `devops.md` | `devops.md` | migration rollback, env vars, CI guards intact, artifact pin |
| UI/UX | `ui_expert.md` | `ui-ux.md` | states, i18n, a11y, design tokens |
| Architect | `architect.md` | `architect.md` | boundaries, ADR present for irreversible choices, no superseded-ADR violation |
For each persona, fully adopt their identity, priorities, and review lens as described in their persona file. Write a review that:
## Step 3 — Write each review
For each persona, write a review that:
- Opens with a one-line verdict: **✅ Approved**, **⚠️ Approved with concerns**, or **🚫 Changes requested**
- Lists concrete findings with file paths and line references where relevant
- Distinguishes blockers (must fix) from suggestions (nice to have)
- Uses the persona's voice and priorities (e.g. Felix cares about TDD and clean code; the security expert checks for injection, auth, and data exposure; the architect checks layer boundaries and coupling)
- Stays focused — only comment on what the persona would actually care about
Format each comment in Markdown with a persona header, e.g.:
- Lists concrete findings with file paths and line references; cite the constitution rule
(e.g. "violates §2.4 — `updatedBy` bound from request body") or the `REQ-NNN` at issue
- Distinguishes **blockers** (must fix) from **suggestions** (nice to have)
- **Requirements Engineer specifically** produces a traceability table — for each `REQ-NNN`:
is it implemented? is there a test? is `rtm.md` updated to `Done`? Any unimplemented or
untested REQ is a blocker. Any code behavior with no backing requirement is flagged
(scope creep — should it be a new REQ, or removed?).
- A constitution **Do-Not-Touch** violation (edited generated file, edited shipped migration,
edited an Accepted ADR, bumped the artifact action past v3, weakened a CI guard) is always
a blocker.
```
## 👨‍💻 Felix Brandt — Senior Fullstack Developer
### 🔐 Security — PR Review
**Verdict: ⚠️ Approved with concerns**
### Blockers
...
- `UserAvatarController.java:42` — REQ-009's 403 path has no test (constitution §2.8)
### Suggestions
...
- ...
```
## Step 4 — Post Comments
## Step 4 — Post comments
Post each persona's review as a **separate comment** on the PR using the Gitea MCP `issue_write` tool (issues and PRs share the comment API in Gitea).
Post each persona's review as a **separate comment** via the Gitea MCP `issue_write` tool
(issues and PRs share the comment API). Post all personas; if one has nothing to flag, post a
brief "LGTM" naming what they checked.
Post all six comments. Do not skip any persona even if their domain has nothing to flag — in that case write a brief "LGTM" with a short explanation of what they checked.
## Step 5 — Report back
## Step 5 — Report Back
After all comments are posted, summarize to the user:
- Which personas posted comments
- The overall verdict across all personas (worst-case wins: if any said "Changes requested", the overall is "Changes requested")
- A bullet list of the top blockers found (if any)
Summarize to the user:
- Each persona's verdict and the overall verdict (worst-case wins: any "Changes requested" → overall "Changes requested")
- The full list of blockers, grouped by persona
- **Traceability status:** which `REQ-NNN` are implemented+tested vs. missing, and whether
`rtm.md` is in sync
- Any constitution Do-Not-Touch violations (called out explicitly)