diff --git a/.claude/commands/spec.md b/.claude/commands/spec.md index 22079353..fc094197 100644 --- a/.claude/commands/spec.md +++ b/.claude/commands/spec.md @@ -12,4 +12,6 @@ Begin by understanding what the user wants to build. Ask clarifying questions ab Then generate a structured spec covering all six core areas: objective, commands, project structure, code style, testing strategy, and boundaries. +If the request bundles several independently testable capabilities, first propose a capability map (module ids, dependency direction, build order) per the skill's Phase 0 and get it approved, then spec each module in dependency order. + Save the spec as SPEC.md in the project root and confirm with the user before proceeding. diff --git a/.gemini/commands/spec.toml b/.gemini/commands/spec.toml index 02b8896c..799f682b 100644 --- a/.gemini/commands/spec.toml +++ b/.gemini/commands/spec.toml @@ -11,5 +11,7 @@ Begin by understanding what the user wants to build. Ask clarifying questions ab Then generate a structured spec covering all six core areas: objective, commands, project structure, code style, testing strategy, and boundaries. +If the request bundles several independently testable capabilities, first propose a capability map (module ids, dependency direction, build order) per the skill's Phase 0 and get it approved, then spec each module in dependency order. + Save the spec as SPEC.md in the project root and confirm with the user before proceeding. """ \ No newline at end of file diff --git a/commands/spec.toml b/commands/spec.toml index 02b8896c..799f682b 100644 --- a/commands/spec.toml +++ b/commands/spec.toml @@ -11,5 +11,7 @@ Begin by understanding what the user wants to build. Ask clarifying questions ab Then generate a structured spec covering all six core areas: objective, commands, project structure, code style, testing strategy, and boundaries. +If the request bundles several independently testable capabilities, first propose a capability map (module ids, dependency direction, build order) per the skill's Phase 0 and get it approved, then spec each module in dependency order. + Save the spec as SPEC.md in the project root and confirm with the user before proceeding. """ \ No newline at end of file diff --git a/evals/cases/spec-driven-development.json b/evals/cases/spec-driven-development.json index 886c51f6..2e9a04d4 100644 --- a/evals/cases/spec-driven-development.json +++ b/evals/cases/spec-driven-development.json @@ -13,6 +13,14 @@ { "prompt": "We are starting a new service, define the requirements first", "top_k": 3 + }, + { + "prompt": "This one requirement covers identity, billing, notifications, and reporting — decompose it into independently specifiable modules first", + "top_k": 3 + }, + { + "prompt": "Before we spec this platform, map the capabilities and their dependency order", + "top_k": 3 } ], "negative": [ @@ -23,6 +31,10 @@ { "prompt": "Simplify this clever one-liner into readable code", "owner": "code-simplification" + }, + { + "prompt": "Break the approved spec into ordered implementation tasks", + "owner": "planning-and-task-breakdown" } ] }, @@ -40,6 +52,21 @@ "A testing strategy is part of the spec", "No implementation code is written" ] + }, + { + "id": 2, + "prompt": "Read portal-brief.md and produce the spec work for the customer portal initiative.", + "expected_output": "A capability map with stable module ids and one-way dependency direction, gated on approval before per-module specs; any module spec written is scoped to its module only", + "files": [ + "spec-driven-development-decomposition" + ], + "expectations": [ + "A capability map with module ids and their dependencies is proposed before any full spec is written", + "Dependency direction is one-way (no cycles) and drives the proposed build order", + "Approval of the map is requested before per-module specs are drafted", + "Any module spec produced is scoped to a single module rather than restating the whole initiative", + "No implementation code is written" + ] } ] } diff --git a/evals/fixtures/spec-driven-development-decomposition/portal-brief.md b/evals/fixtures/spec-driven-development-decomposition/portal-brief.md new file mode 100644 index 00000000..c8ecafe9 --- /dev/null +++ b/evals/fixtures/spec-driven-development-decomposition/portal-brief.md @@ -0,0 +1,22 @@ +# Customer portal — product brief + +Leadership wants a self-serve customer portal shipped as one initiative. The +request, as handed down: + +- Customers sign in with email/password or company SSO and manage their + account and team members. +- Customers pick a plan, enter payment details, and receive monthly invoices; + plan changes prorate. +- Customers get email notifications for invoices, payment failures, and team + invitations; enterprise customers can register webhooks for the same events. +- Admins see a usage dashboard: seats, API calls, and spend per month. + +Constraints gathered so far: + +- Billing must know who the customer is, so it depends on account data. +- Notifications fire on billing and account events. +- The dashboard reads from billing and notification delivery records. +- The four areas have different reviewers: platform owns accounts, finance + owns billing, and growth owns notifications and the dashboard. +- Each area should be shippable and verifiable on its own; finance wants to + sign off on billing without waiting for the dashboard. diff --git a/skills/spec-driven-development/SKILL.md b/skills/spec-driven-development/SKILL.md index 569d2232..eee64852 100644 --- a/skills/spec-driven-development/SKILL.md +++ b/skills/spec-driven-development/SKILL.md @@ -1,6 +1,6 @@ --- name: spec-driven-development -description: Creates specs before coding. Use when starting a new project, feature, or significant change and no specification exists yet. Use when requirements are unclear, ambiguous, or only exist as a vague idea. +description: Creates specs before coding. Use when starting a new project, feature, or significant change and no specification exists yet. Use when requirements are unclear, ambiguous, or only exist as a vague idea. Use when a single requirement spans several independently testable capabilities and needs decomposing into a capability map of modules before specifying. --- # Spec-Driven Development @@ -21,7 +21,7 @@ Write a structured specification before writing any code. The spec is the shared ## The Gated Workflow -Spec-driven development has four phases. Do not advance to the next phase until the current one is validated. +Spec-driven development has four phases, preceded by a scope check (Phase 0) that activates only when one request bundles several independently testable capabilities. Do not advance to the next phase until the current one is validated. ``` SPECIFY ──→ PLAN ──→ TASKS ──→ IMPLEMENT @@ -31,6 +31,39 @@ SPECIFY ──→ PLAN ──→ TASKS ──→ IMPLEMENT reviews reviews reviews reviews ``` +### Phase 0: Scope Check + +Most requests describe one capability. If this one does, skip this phase and go straight to Specify — Phase 0 exists for the exception, not the rule, and it puts no hierarchy on single-capability features. + +**Detection.** Decompose before specifying when a single requirement bundles several independently testable capabilities: + +- The requirement names distinct capabilities with their own consumers or data (e.g. identity, billing, notifications, reporting) +- Acceptance criteria cluster into groups that could ship and be verified separately +- One capability could be cut or replaced without rewriting the others' requirements + +**Propose a capability map before writing any spec.** Small and reviewable — a module table plus a build order, not a project plan: + +```markdown +# Capability Map: [Initiative Name] + +| Module id | Responsibility | Depends on | +|---|---|---| +| identity | Accounts, sessions, SSO | — | +| billing | Plans, invoices, payments | identity | +| notifications | Email and webhook fan-out | identity | +| reporting | Usage dashboards | billing, notifications | + +Build order: identity → billing, notifications → reporting +``` + +- **Stable module ids.** Kebab-case, chosen once, never renamed mid-initiative. Specs, plans, and downstream commands select work by these ids instead of guessing which spec is active. +- **Dependency direction, no cycles.** Arrows point one way. If two modules each need the other, they are one module. +- **Interfaces live at the boundary.** The map records that `billing` depends on `identity`; the contract between them belongs in the provider module's spec (see `api-and-interface-design` for designing it). + +**The map is gated like every phase.** The human reviews module boundaries, dependency direction, and build order before any module spec is written. Getting the map wrong is expensive; reviewing ten lines is not. + +**Then recurse per module.** Run Specify → Plan → Tasks → Implement for each module in dependency order. Each module gets its own spec, scoped to that module's objective, boundaries, and success criteria. Save the approved map at the project root and each module's spec alongside it, named by module id (`SPEC-identity.md`, `SPEC-billing.md`) — the map, not filename guessing, is the index of what exists. + ### Phase 1: Specify Start with a high-level vision. Ask the human clarifying questions until requirements are concrete. @@ -186,6 +219,8 @@ The spec is a living document, not a one-time artifact: | "The spec will slow us down" | A 15-minute spec prevents hours of rework. Waterfall in 15 minutes beats debugging in 15 hours. | | "Requirements will change anyway" | That's why the spec is a living document. An outdated spec is still better than no spec. | | "The user knows what they want" | Even clear requests have implicit assumptions. The spec surfaces those assumptions. | +| "It's one big feature; splitting it is overhead" | If acceptance criteria cluster into independently testable groups, a monolithic spec forces every downstream task to reason over the whole contract. A ten-line capability map is the cheap alternative. | +| "I'll decompose during planning" | Planning slices tasks within a spec. By then the oversized artifact already exists — module boundaries and dependency direction must be decided before the spec is written, not after. | ## Red Flags @@ -194,6 +229,8 @@ The spec is a living document, not a one-time artifact: - Implementing features not mentioned in any spec or task list - Making architectural decisions without documenting them - Skipping the spec because "it's obvious what to build" +- One spec whose requirements span several independently testable capabilities +- Module boundaries or build order decided implicitly during implementation because no capability map was approved up front ## Verification @@ -204,3 +241,5 @@ Before proceeding to implementation, confirm: - [ ] Success criteria are specific and testable - [ ] Boundaries (Always/Ask First/Never) are defined - [ ] The spec is saved to a file in the repository +- [ ] If the request bundles several independently testable capabilities, a capability map (module ids, dependency direction, build order) was approved before any module spec was written +- [ ] Every module spec traces to a module id in the approved map