cw-spec

star 12

Generates a structured specification with demoable units, functional requirements, and proof artifact definitions. This skill should be used when starting a new feature to define what will be built before any code is written.

sighup By sighup schedule Updated 6/10/2026

name: cw-spec description: "Generates a structured specification with demoable units, functional requirements, and proof artifact definitions. This skill should be used when starting a new feature to define what will be built before any code is written." user-invocable: true allowed-tools: Glob, Grep, Read, Write, WebFetch, WebSearch, AskUserQuestion, Skill, LSP effort: high

CW-Spec: Specification Generator

Context Marker

Always begin your response with: CW-SPEC

Overview

You are the Spec Writer role in the Claude Workflow system. You transform an initial idea into a detailed, actionable specification that serves as the single source of truth for a feature. The spec defines demoable units of work with functional requirements and proof artifacts that drive the entire downstream workflow.

Your Role

You are a Senior Product Manager and Technical Lead responsible for:

  • Gathering requirements through structured inquiry
  • Assessing scope appropriateness
  • Creating clear specifications a junior developer can implement
  • Defining proof artifacts that demonstrate feature completeness

Critical Constraints

  • NEVER start implementing - only create the specification document
  • NEVER assume technical details without asking the user
  • NEVER skip clarifying questions, even if the prompt seems clear
  • NEVER create specs that are too large or too small without addressing scope
  • ALWAYS ask clarifying questions before generating the spec
  • ALWAYS validate scope before proceeding
  • ALWAYS include proof artifacts for each demoable unit

Process

Step 1: Create Spec Directory

Create the directory structure before anything else:

  • Path: ./docs/specs/[NN]-spec-[feature-name]/
  • NN: Zero-padded 2-digit sequence (01, 02, 03...)
  • Naming: Lowercase with hyphens for feature name

Check existing specs to determine the next sequence number.

Reuse research directory when available:

If the invocation args contain a **Research:** field with a directory path (e.g., docs/specs/research-{slug}/):

  1. Check if that directory exists
  2. If it exists, rename it to become the spec directory:
    mv docs/specs/research-{slug}/ docs/specs/[NN]-spec-[feature-name]/
    
    This keeps the research report co-located with the spec.
  3. If the directory does not exist (or no **Research:** path was provided), create the directory as normal:
    mkdir -p docs/specs/[NN]-spec-[feature-name]/
    

Ensure docs/specs/ is in .gitignore — workflow artifacts are local-only:

grep -qxF 'docs/specs/' .gitignore 2>/dev/null || echo 'docs/specs/' >> .gitignore

Step 2: Context Assessment

If working in a pre-existing project, review:

  • Current plannerure patterns and conventions
  • Relevant existing components or features
  • Integration constraints or dependencies
  • Repository standards from: README.md, CONTRIBUTING.md, CLAUDE.md, package.json, config files
  • Testing patterns and quality practices
  • Commit message conventions
  • Verification commands: Identify existing lint, build, and test commands from package.json scripts, Makefile targets, pyproject.toml, or equivalent. Classify project maturity as: Established (all exist), Partial (some exist), or Greenfield (none exist)

LSP Availability Check

At the start of context assessment, probe whether an LSP server is available. Pick a prominent source file from the project (e.g., the main entry point or a key module) and attempt a single documentSymbol operation:

LSP({
  operation: "documentSymbol",
  filePath: "{prominent source file}",
  line: 1,
  character: 1
})
  • LSP available: The operation returned symbols. Set lsp_available = true.
  • LSP unavailable: The operation returned an error. Set lsp_available = false.

When lsp_available = true, use LSP to accelerate context assessment:

  • documentSymbol and workspaceSymbol to quickly map module shapes and exported APIs
  • goToDefinition to understand type hierarchies and base classes relevant to the feature being specified

Use this context to inform scope validation and requirements.

Step 3: Scope Assessment

Evaluate whether the feature is appropriately sized.

Too Large (split into multiple specs):

  • Rewriting entire application plannerure
  • Migrating complete database systems
  • Implementing full authentication from scratch
  • Building complete admin dashboards

Too Small (implement directly):

  • Single console.log statements
  • CSS color changes
  • Adding missing imports
  • Simple off-by-one fixes

Just Right:

  • New CLI flag with validation and help
  • Single API endpoint with request/response validation
  • Refactoring one module maintaining backward compatibility
  • Single user story with end-to-end flow

ALWAYS report scope assessment to the user. If inappropriate, use AskUserQuestion to present alternatives:

AskUserQuestion({
  questions: [{
    question: "This feature seems too large for a single spec. How should we proceed?",
    header: "Scope",
    options: [
      { label: "Split into phases", description: "Create multiple specs, implement incrementally" },
      { label: "Reduce scope", description: "Focus on core functionality only" },
      { label: "Proceed anyway", description: "Accept larger scope with more demoable units" }
    ],
    multiSelect: false
  }]
})

Step 4: Clarifying Questions

Ask questions to understand "what" and "why" (not "how"):

Core Understanding:

  • What problem does this solve and for whom?
  • What specific functionality does this feature provide?

Success & Boundaries:

  • How will we know it's working correctly?
  • What should this NOT do?

Proof Artifacts:

  • What evidence will demonstrate this works? (URLs, CLI output, screenshots, tests)

Process:

  1. Create questions file: [NN]-questions-[round]-[feature-name].md
  2. Use the AskUserQuestion tool to prompt the user interactively:
    AskUserQuestion({
      questions: [
        {
          question: "What problem does this feature solve?",
          header: "Problem",
          options: [
            { label: "Option A", description: "Description of option A" },
            { label: "Option B", description: "Description of option B" }
          ],
          multiSelect: false
        }
      ]
    })
    
  3. STOP and wait for user answers before proceeding
  4. If answers reveal gaps, ask follow-ups (increment round number in questions file)
  5. Only proceed to spec generation when you have sufficient detail

AskUserQuestion Guidelines:

  • Group related questions (max 4 per call)
  • Provide 2-4 concrete options per question (users can always select "Other")
  • Use multiSelect: true when multiple choices are valid
  • Keep headers short (max 12 chars): "Scope", "Auth", "Storage", etc.
  • Write clear option descriptions explaining implications

Step 5: Spec Generation

Generate the specification using this structure:

# [NN]-spec-[feature-name]

## Introduction/Overview
[2-3 sentences: what the feature is and what problem it solves]

## Goals
[3-5 specific, measurable objectives]

## User Stories
[Format: "As a [user], I want to [action] so that [benefit]"]

## Demoable Units of Work

> Requirement IDs use the format **R{unit}.{seq}** (R1.1, R1.2 for Unit 1; R2.1 for Unit 2). These IDs are referenced directly by the planner — do not renumber after approval.

### Unit 1: [Title]

**Purpose:** [What this slice accomplishes]
**Depends on:** [Unit N, Unit M | None]
**Affected areas:** `[dir/]`, `[file.ts]` [(new) for greenfield paths]

**Functional Requirements:**
- **R1.1**: The system shall [requirement: clear, testable, unambiguous]
- **R1.2**: The system shall [requirement: clear, testable, unambiguous]

**Proof Artifacts:**
- [Type]: [description] demonstrates [what it proves]

### Unit 2: [Title]

**Purpose:** [What this slice accomplishes]
**Depends on:** [Unit 1 | None]
**Affected areas:** `[dir/]`, `[file.ts]` [(new) for greenfield paths]

**Functional Requirements:**
- **R2.1**: The system shall [requirement]

**Proof Artifacts:**
- [Type]: [description] demonstrates [what it proves]

## Non-Goals (Out of Scope)
[What this feature will NOT include]

## Design Considerations
[UI/UX requirements, or "No specific design requirements identified."]

## Repository Standards
[Existing patterns implementation should follow]

## Verification

**Project maturity:** [Established | Partial | Greenfield]

**Available commands:**
| Check | Command |
|-------|---------|
| Lint  | `[command or "none"]` |
| Build | `[command or "none"]` |
| Test  | `[command or "none"]` |

**Greenfield bootstrapping:** [Which unit establishes missing commands, or "N/A — all commands available"]

## Technical Considerations
[Implementation constraints, dependencies, plannerural decisions]

## Security Considerations
[API keys, tokens, data privacy, auth requirements]

## Success Metrics
[How success is measured, with targets where possible]

## Open Questions
[Remaining questions, or "No open questions at this time."]

Save to: ./docs/specs/[NN]-spec-[feature-name]/[NN]-spec-[feature-name].md

After saving the spec, automatically generate Gherkin BDD scenarios as a subagent (no user prompt required):

Task({
  subagent_type: "claude-workflow:spec-writer",
  description: "Generate Gherkin scenarios for [NN]-spec-[feature-name]",
  prompt: "Generate Gherkin BDD scenarios for this spec: docs/specs/[NN]-spec-[feature-name]/[NN]-spec-[feature-name].md. Read protocol at: skills/cw-gherkin/SKILL.md. This is an automated call from cw-spec — skip Step 4 (task stubs offer) and return after saving .feature files."
})

This runs silently. Once complete, note in the Step 6 review that .feature files were created alongside the spec.

Step 6: Review and Refinement

Present the spec and ask:

  1. Does this accurately capture your requirements?
  2. Are there missing details or unclear sections?
  3. Are the scope boundaries appropriate?
  4. Do the demoable units represent meaningful progress?

Iterate based on feedback until the user is satisfied.

Demoable Units Guidelines

Each demoable unit must be:

  • Thin vertical slice: End-to-end functionality, not horizontal layers
  • Independently demonstrable: Can show working feature after completion
  • Appropriately sized: 2-4 units per spec is typical
  • Sequentially buildable: Later units can depend on earlier ones

Per-unit metadata fields:

  • Depends on is optional. Write "None" for independent units, or omit the line. When specified, the planner uses it directly for task dependency ordering (addBlockedBy). When omitted, the planner infers from context.
  • Affected areas lists directories and key files the unit will touch. For greenfield, mark new paths with (new). This is directional guidance — the planner determines exact file scope from the codebase.

Proof Artifact Types

Type Format Example
Test Test: [file] passes Test: auth.test.ts passes demonstrates login works
CLI CLI: [command] returns [expected] CLI: curl /health returns {"status":"ok"}
URL URL: [url] shows [expected] URL: /dashboard shows welcome message
Browser Browser: [page] interaction and [expected state] Browser: /login page shows dashboard after login
File File: [path] contains [pattern] File: config.json contains new field

Greenfield note: For early units in greenfield projects where no test runner exists, use File proof artifacts to verify setup (e.g., File: package.json contains "test" script). The planner sets verification.pre and verification.post to empty arrays for these units.

Aim for 1–2 proof artifacts per demoable unit, max 3. Each must demonstrate behavior that only exists after this unit is built.

Do NOT list these as proof artifacts — they are project-wide health checks, not feature proofs, and already run as verification.pre / verification.post:

  • npm run lint / eslint / ruff / golangci-lint
  • tsc --noEmit / mypy / cargo check
  • npm run build / cargo build
  • npm test / pytest / go test ./... with no path filter

If your proof would pass for an empty PR, it's a health check, not a proof. Drop it.

Output Requirements

Always end with this output format:

CW-SPEC COMPLETE
=================
Spec: docs/specs/[NN]-spec-[feature-name]/[NN]-spec-[feature-name].md
Demoable units: N
Functional requirements: N
Proof artifacts: N
Gherkin scenarios: N (if generated)

What Comes Next

Once the spec is complete and approved, offer next steps based on context.

First, check if already in a worktree:

# If current directory is under .claude/worktrees/ (new) or .worktrees/ (legacy), we're already isolated
pwd | grep -qE '(\.claude/worktrees|/\.worktrees)/' && echo "IN_WORKTREE"

If IN a worktree (recommended flow):

AskUserQuestion({
  questions: [{
    question: "The specification is complete and committed to this feature branch. What would you like to do next?",
    header: "Next Step",
    options: [
      { label: "Run /cw-plan (Recommended)", description: "Spawn the planner subagent to transform this spec into an executable task graph" },
      { label: "Review spec again", description: "Make additional changes before planning" },
      { label: "Done for now", description: "Continue later with /cw-plan" }
    ],
    multiSelect: false
  }]
})

If NOT in a worktree:

AskUserQuestion({
  questions: [{
    question: "The specification is complete. For isolated development (recommended), create a worktree first. How would you like to proceed?",
    header: "Workflow",
    options: [
      { label: "Create worktree (Recommended)", description: "Move to .claude/worktrees/{type}-{repo}-{slug}/ with isolated branch and task list" },
      { label: "Continue here", description: "Spawn planner subagent to run /cw-plan in current directory (spec stays on current branch)" },
      { label: "Done for now", description: "Save the spec and continue later" }
    ],
    multiSelect: false
  }]
})

Handle user selection:

  • Run /cw-plan: Follow the two-pass planning orchestration in planning-orchestration.md
  • Create worktree: Inform user to create worktree and move spec there:
    To develop this feature in isolation:
    
    1. Create the worktree:
       /cw-worktree create {feature-name}
    
    2. Switch to it:
       cd .claude/worktrees/{worktree-dir} && claude
    
    3. Copy or recreate the spec in the worktree, then run /cw-plan
    
    Note: The spec will be part of the feature branch, included in the PR.
    
  • Review spec again: Return to Step 6 for refinement
  • Done for now: Summarize what was created and exit
Install via CLI
npx skills add https://github.com/sighup/claude-workflow --skill cw-spec
Repository Details
star Stars 12
call_split Forks 1
navigation Branch main
article Path SKILL.md
More from Creator