From 04aaddc5ac629f0e30079a4942a5d1eec275e114 Mon Sep 17 00:00:00 2001 From: Vanessa-Ts Date: Sat, 13 Jun 2026 17:46:44 +0200 Subject: [PATCH 1/4] Rewrite spec-feature skill: 2-phase interview with 3-artifact output --- .claude/skills/spec-feature/SKILL.md | 156 ++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 25 deletions(-) diff --git a/.claude/skills/spec-feature/SKILL.md b/.claude/skills/spec-feature/SKILL.md index 1d298dc..1198bb1 100644 --- a/.claude/skills/spec-feature/SKILL.md +++ b/.claude/skills/spec-feature/SKILL.md @@ -7,55 +7,160 @@ ## Purpose -Before writing a plan or any code, capture requirements through a structured interview. The output is a `docs/specs/.md` file that feeds into `/plan`. +Before writing a plan or any code, capture requirements and design through a structured two-phase interview. The output is three files under `docs/specs//`: `requirements.md`, `design.md`, and `tasks.md`. --- -## Interview — 6 questions +## EARS notation guide + +``` +EARS (Easy Approach to Requirements Syntax) — five stems: + Ubiquitous: The system shall . + Event-driven: When , the system shall . + Unwanted: If , then the system shall . + State-driven: While , the system shall . + Optional: Where , the system shall . +Use "When … the system shall …" for the majority of API feature stories. +Never combine two stems in one sentence. +``` + +--- + +## Interview — Phase 1: Requirements (questions 1–5) + +Ask these questions **one at a time** (wait for the answer before asking the next): + +1. **Actor** — Who uses it? Which user role or system trigger? +2. **Behaviour** — What must it do? Use EARS stem: "When [condition], the system shall [behaviour]." (1–3 stories) +3. **Motivation** — Why now? What is the business motivation and cost of deferral? +4. **Acceptance criteria** — List 3–5 specific, testable conditions that mean "done". Format: "Given / When / Then." +5. **NFRs + success metrics** — Latency target, auth/authz scope, error observability, and one measurable KPI. + +After question 5: + +- Write `docs/specs//requirements.md` (see template below). +- Show the path to the user. +- Ask: + > "Does this capture the requirements correctly? Reply **yes** to continue to design, or correct anything above." +- **Do not proceed to phase 2 until the user replies yes.** + +--- + +## Interview — Phase 2: Design (questions 6–8) Ask these questions **one at a time** (wait for the answer before asking the next): -1. **Who uses it?** — which user role or system actor triggers this feature? -2. **What does it do?** — one sentence: "Given X, when Y, then Z." -3. **Why now?** — what problem or opportunity drives this? What's the cost of not building it? -4. **Acceptance criteria** — list 3–5 specific, testable conditions that mean "done". Format: "Given / When / Then." -5. **Edge cases & constraints** — what inputs, states, or conditions must be explicitly handled or rejected? -6. **Out of scope** — what related things will NOT be built in this iteration? +6. **API shape** — HTTP method(s), path(s), request fields, response fields. +7. **Data model** — Entity fields and types (no code); relations to existing models. +8. **Technical constraints** — Anything limiting implementation beyond project defaults (stack limits, third-party APIs, etc.). + +After question 8: + +- Write `docs/specs//design.md` (see template below). +- Immediately write `docs/specs//tasks.md` (see template below). + +Final message (exact string): +``` +Spec written to docs/specs// — run /plan to produce the implementation plan. +``` --- -## Output — `docs/specs/.md` +## Output templates + +### `requirements.md` ```markdown -# Spec: +# Requirements: **Date**: -**Author**: -**Status**: draft - -## Summary -One sentence: Given X, when Y, then Z. +**Author**: +**Status**: approved ## Actor - + ## Motivation - + + +## User stories (EARS) +- When , the system shall . +- ... ## Acceptance criteria - [ ] Given , when , then - [ ] ... -## Edge cases & constraints -- -- ... +## Non-functional requirements +- **Performance**: +- **Security**: +- **Observability**: + +## Success metrics / KPIs +- ## Out of scope -- -- ... +- ## Open questions -- +- +``` + +### `design.md` + +```markdown +# Design: + +## API contracts + +| Method | Path | Request | Response | Status codes | +|---|---|---|---|---| +| | | | | 200, 404, 422 | + +## Pydantic model sketches + +**** +- ``: `` +- ... + +## BCE layer decisions +- **Route**: +- **Service/Control**: +- **Store/Entity**: + +## Sequence diagram + +```mermaid +sequenceDiagram + actor User + participant Route + participant Service + participant Store + User->>Route: + Route->>Service: + Service->>Store: + Store-->>Service: + Service-->>Route: + Route-->>User: +``` + +## Technical constraints +- Stack: FastAPI, Pydantic v2, uv, Python 3.11+, mypy --strict +- +``` + +### `tasks.md` + +```markdown +# Tasks: + +Ordered commit checklist — implement in this sequence: + +- [ ] **models** — define Pydantic models in `src/app/models/.py` +- [ ] **store** — implement persistence layer in `src/app/store/.py` +- [ ] **routes** — implement route handlers in `src/app/routes/.py`; wire into `main.py` +- [ ] **tests** — write happy path, 422, and 404 tests in `tests/test_.py` +- [ ] run `/plan ` to produce the implementation plan ``` --- @@ -63,6 +168,7 @@ One sentence: Given X, when Y, then Z. ## Rules - Never invent requirements — only write what the user confirmed. -- "Open questions" must list anything that could not be resolved in the interview. -- After writing the spec, tell the user: `Spec written to docs/specs/.md — run /plan to produce the implementation plan.` +- Ask questions one at a time; never batch multiple questions in one message. +- Do not proceed to phase 2 until the user explicitly approves `requirements.md`. +- "Open questions" in `requirements.md` must list anything unresolved after phase 1. - Do not start the plan or write any code. From b32ca23fe96e7ab939d4a91d091b49b223c61c40 Mon Sep 17 00:00:00 2001 From: Vanessa-Ts Date: Sat, 13 Jun 2026 17:47:12 +0200 Subject: [PATCH 2/4] Update inventory.md: spec-feature row from reuse-as-is to rebuild --- docs/inventory.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/inventory.md b/docs/inventory.md index fc7961d..7fbf6f0 100644 --- a/docs/inventory.md +++ b/docs/inventory.md @@ -19,7 +19,7 @@ External reference sources checked: | `skills/pytest-patterns/SKILL.md` | project-internal | proprietary | ✓ for any httpx+pytest-asyncio project | — | — | Bans `TestClient`, enforces `AsyncClient+ASGITransport`, documents fixture baseline and 3-test minimum. No project-specific logic; portable as-is. | | `skills/uv-workflows/SKILL.md` | project-internal | proprietary | ✓ for any uv-managed Python project | — | — | Documents `uv add`, `uv sync`, `uv run` idioms and bans `pip`/`poetry`. Fully generic; reuse verbatim in any Python project using uv. | | `skills/infrastructure/SKILL.md` | project-internal | proprietary | ✓ for any Python+uv project with Docker/CI | — | — | Multi-stage Dockerfile, docker-compose healthchecks, GitHub Actions with `astral-sh/setup-uv`, Helm chart structure. Stack-agnostic patterns; swap `pytest` for your test runner. | -| `skills/spec-feature/SKILL.md` | project-internal | proprietary | ✓ | — | — | 6-question interview template producing `docs/specs/.md`. Fully generic; no framework coupling. | +| `skills/spec-feature/SKILL.md` | project-internal | proprietary | — | — | ✓ | Rebuilt: 2-phase 8-question interview (requirements + design) with approval gate; produces 3 files under `docs/specs//` (`requirements.md`, `design.md`, `tasks.md`). EARS notation embedded. | | `skills/openapi/SKILL.md` | project-internal | proprietary | ✓ for any FastAPI/Python project | — | — | OpenAPI 3.x YAML structure, `datamodel-codegen` and `fastapi-codegen` usage, spec export from running FastAPI app. | | `skills/review/SKILL.md` | project-internal | proprietary | — | ✓ | — | Inline BCE + FastAPI + Python checklist. Wrap: replace FastAPI-specific items for non-FastAPI stacks. | | `skills/doc/SKILL.md` | project-internal | proprietary | — | ✓ | — | Doc-generation workflow reading `main.py`, routes, models, config. Wrap: adjust source paths for non-FastAPI layouts. | From a1591d1570a44da5c029fd66a7f9a5cab3a5bb1f Mon Sep 17 00:00:00 2001 From: Vanessa-Ts Date: Sat, 13 Jun 2026 17:47:35 +0200 Subject: [PATCH 3/4] Update CLAUDE.md skill map: spec-feature now produces 3 output files --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 2b1fe98..8c97c85 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -104,7 +104,7 @@ The `pre_push_quality_gate` hook enforces this inline on every `git push`. | `pytest-patterns` skill | Auto-loads for `tests/`, `conftest.py` | | `uv-workflows` skill | Auto-loads for `pyproject.toml`, `uv.lock` | | `infrastructure` skill | Auto-loads for `Dockerfile`, `docker-compose*`, CI workflows, Helm | -| `spec-feature` skill | Structured interview → `docs/specs/.md` before planning | +| `spec-feature` skill | 2-phase interview → `docs/specs//{requirements,design,tasks}.md` before planning | | `openapi` skill | Auto-loads for `openapi*.yml/json`; spec authoring and codegen | | `review` skill | Inline BCE + FastAPI + Python checklist for ad-hoc code review | | `doc` skill | Reads source → writes project docs into `docs/` | From 3f3d061d8d06ca53b162ef7d20e96fb2d1dbcb49 Mon Sep 17 00:00:00 2001 From: Vanessa-Ts Date: Sat, 13 Jun 2026 18:00:34 +0200 Subject: [PATCH 4/4] Fix nested code fence in design.md template --- .claude/skills/spec-feature/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude/skills/spec-feature/SKILL.md b/.claude/skills/spec-feature/SKILL.md index 1198bb1..b416088 100644 --- a/.claude/skills/spec-feature/SKILL.md +++ b/.claude/skills/spec-feature/SKILL.md @@ -108,7 +108,7 @@ Spec written to docs/specs// — run /plan to produce the imp ### `design.md` -```markdown +````markdown # Design: ## API contracts @@ -147,7 +147,7 @@ sequenceDiagram ## Technical constraints - Stack: FastAPI, Pydantic v2, uv, Python 3.11+, mypy --strict - -``` +```` ### `tasks.md`