plugins/sdlc-utils/skills/spec-writing/SKILL.md
Specification writing and lifecycle management for software development. Use when the user asks to "write a spec", "create a specification", "document requirements", "spec out a feature", "manage a spec through its lifecycle", "move a spec to live", "archive a spec", "update a spec", or "verify implementation against a spec". Covers creating specs from requirements, managing the spec lifecycle (draft → reviewed → in-progress → live → deprecated → archive), keeping specs as living documents, and using specs for verification.
npx skillsauth add nsheaps/ai-mktpl spec-writingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Guide for writing, maintaining, and managing specifications through their complete lifecycle. Specifications are a critical tool for ensuring alignment between requirements, design, and implementation.
Specifications move through six states, tracked via a status field in the
frontmatter of each spec file:
---
name: feature-name
status: draft # draft | reviewed | in-progress | live | deprecated | archive
---
The status field replaces file directory organization, allowing specs to remain in a single location while their lifecycle state evolves. This approach is cleaner and easier to track than moving files between folders.
Purpose: Initial exploration and brainstorming
When to use:
Characteristics:
[TBD] and [NEEDS RESEARCH] sectionsNext step: Update status to reviewed after review and approval
Purpose: Formally approved specifications ready for implementation
When to use:
Characteristics:
[TBD] items have been resolvedNext step: Update status to in-progress when implementation begins
Purpose: Specifications actively being implemented
When to use:
Characteristics:
Next step: Update status to live when implementation is complete and deployed
Purpose: Finalized specifications for actively used features
When to use:
Characteristics:
Next step: Update status to deprecated when feature is phased out (while still in
use), or archive when completely removed
Purpose: Outdated specifications for features still in use
When to use:
Characteristics:
Next step: Update status to archive when feature is fully removed
Purpose: Historical reference for removed features
When to use:
Characteristics:
Every spec file must include YAML frontmatter. The formal schema is defined in
schemas/spec-frontmatter.yaml (relative to the sdlc-utils plugin root).
| Field | Type | Description |
| -------- | ------ | ------------------------------------------------------------------------ |
| name | string | Unique identifier for the spec (kebab-case) |
| status | string | Lifecycle stage: draft, reviewed, in-progress, live, deprecated, archive |
| Field | Type | Description |
| ------------- | -------- | ------------------------------------------- |
| description | string | One-line summary of what the spec covers |
| parent | string | Name of parent spec (for child specs) |
| related | string[] | Names of related specs to consider together |
| owner | string | Who is responsible for this spec |
| created | date | When the spec was first created |
| updated | date | When the spec was last updated |
| tags | string[] | Categorization tags |
When creating or reviewing a spec, verify that:
name and status must existname is kebab-case — e.g., user-authentication, not User Authenticationstatus is a valid enum value — one of: draft, reviewed, in-progress, live,
deprecated, archiveYYYY-MM-DD (e.g., 2026-04-06)parent references an existing spec — if set, the named spec should existrelated entries reference existing specs — each name should correspond to
a real spec fileUse the combined format: one document containing both Problem & Requirements and Technical Design. Do not separate into distinct "PRD" and "tech spec" documents.
Recommended sections:
# [Feature Name]
## Problem & Requirements
### Problem Statement
What problem does this solve? Who is affected? Why is it urgent?
### Requirements
What needs to be true? List specific, testable requirements.
### Success Metrics
How will we know this is successful?
### Out of Scope
What deliberately is NOT included?
## Technical Design
### Architecture Overview
High-level system design and component interactions.
### Implementation Details
Specific implementation approach, libraries, patterns, and constraints.
### Error Handling & Edge Cases
What happens when things go wrong?
### Testing Strategy
How will this be tested?
### Migration & Rollout
Any migration steps or phased rollout needed?
## Next Steps
What remains to be done? Who is responsible?
See references/spec-template.md for a complete template with guidance on
each section.
Target: 200-500 lines
If your spec exceeds 500 lines:
Example:
docs/specs/draft/search-feature.md (parent - 300 lines)
docs/specs/draft/search-indexing.md (child - 200 lines)
docs/specs/draft/search-query-language.md (child - 250 lines)
For complex projects with many specs, organize specs into feature-specific folders to keep related specs grouped together:
docs/specs/
├── settings-modal/
│ ├── settings-modal.md # parent spec
│ ├── general-tab.md # child spec
│ ├── appearance-tab.md # child spec
│ └── keybindings-tab.md # child spec
├── auth/
│ ├── auth-overview.md # parent spec
│ ├── oauth-flow.md # child spec
│ └── session-management.md # child spec
├── search/
│ ├── search-overview.md # parent spec
│ ├── search-indexing.md # child spec
│ └── search-query-language.md # child spec
Guidelines for folder organization:
status field — Status is tracked in frontmatter,
not in the directory structureGood requirements are specific, testable, and unambiguous.
| Poor | Better | | ----------------------------- | -------------------------------------------- | | "Fast API responses" | "API responds in <200ms at p95" | | "User-friendly interface" | "Onboarding completes in <3 clicks" | | "Robust error handling" | "Network errors are retried 3x with backoff" | | "Supports various file types" | "Supports PDF, DOCX, PNG files" |
As you implement, the spec becomes a reference and record:
The spec is a checklist for reviewers:
The spec is the source of truth for behavior:
Once implementation is complete, use the spec to verify work:
If implementation differs from the spec:
Never silently ignore divergence. Always document the decision.
| Anti-Pattern | Instead | | -------------------------------- | -------------------------------------------- | | Writing elaborate specs one-shot | Iterate through draft → review → refine | | Separating PRD from tech spec | Use one combined document | | Specs as decoration | Living doc, updated as implementation learns | | Ignoring spec divergence | Always resolve and document divergence | | Specs too long (1000+ lines) | Split into parent + child specs | | Vague requirements | Specific, measurable, testable criteria | | Outdated specs in "live" | Update immediately when implementation | | | changes | | Specs in wrong directory | Use correct lifecycle directory |
Each development cycle should review and update the spec:
1. Planning → Review and refine spec
2. Design → Update spec with technical decisions
3. Implementation → Keep spec in sync with code
4. Testing → Verify implementation against spec
5. Review → Check spec alignment during code review
6. Deployment → Move spec to "live" (or "deprecated")
7. Maintenance → Treat spec as source of truth
Organize specs in a single docs/specs/ directory, optionally grouped by
feature if the project has many specs (see "Folder Organization for Larger
Projects" above). Track the lifecycle status of each spec using the status
field in its frontmatter, not by moving files between directories.
Basic structure:
docs/specs/
├── feature-a.md # Single spec, all statuses in one file
├── feature-b.md
└── feature-group/ # Specs grouped by feature area (optional)
├── parent-spec.md
├── child-spec-1.md
└── child-spec-2.md
File naming: Use descriptive names: user-authentication.md,
search-indexing.md, payment-webhook.md (not spec1.md, tmp.md, etc.)
Names should reflect the feature or component, not the status.
references/spec-template.md — Complete spec template with all sections
and filling guidance. Copy as a starting point for new specs.mantras-and-incremental-development.md — Defines spec-driven development
and the spec lifecycle directory structuretools
Manually reproduce what the github-app plugin's SessionStart hook does to make a GitHub App installation token usable in the current session — materialize the PEM, generate the token, isolate GH_CONFIG_DIR, write the runtime env file, and wire CLAUDE_ENV_FILE so every Bash call sees GH_TOKEN/GITHUB_TOKEN. Use when the hook did not run, the token is missing from the environment, or a shell/teammate needs the token wired up by hand. <example>GH_TOKEN isn't set even though github-app is configured</example> <example>the github-app SessionStart hook didn't run, set up the token manually</example> <example>wire the github app token into CLAUDE_ENV_FILE</example> <example>gh keeps falling back to the wrong account, isolate GH_CONFIG_DIR</example>
tools
Manually configure the GitHub App bot git identity the way the github-app plugin's SessionStart hook does — resolve the app slug and bot user ID, build the <slug>[bot] name and noreply email, set GIT_AUTHOR_*/GIT_COMMITTER_* env vars, and write an isolated GIT_CONFIG_GLOBAL with the gh auth git-credential helper. Use when commits are attributed to the wrong account, "Author identity unknown" appears, or git identity must be set up by hand. <example>my commits are showing up as the handler, not the bot</example> <example>git says Author identity unknown after the github-app hook ran</example> <example>configure the github app bot git identity manually</example> <example>set up the gh credential helper for git push</example>
tools
Manages spec files for requirements capture and validation
tools
# Bash Chaining Alternatives This skill teaches you how to work around the bash command chaining restriction enforced by this plugin. ## Why Chaining is Blocked The `bash-command-rejection` plugin blocks these operators: | Operator | Name | Why Blocked | | -------- | ---------- | ----------------------------------------------------------------------------------- | | `&&` | AND chain | Runs cmd2 only if cmd1 su