Ss sdd writing specs
Skill Emrebener/Sublime-Skills/skills/spec-driven-development/ss-sdd-writing-specs
Use during the spec-drafting stage of an SDD pipeline run, immediately after ss-sdd-discovering-requirements has produced a shared understanding. Renders that understanding into a formal spec.md artifact at docs/specs/NNN-short-name/spec.md.From its SKILL.md
npx -y skills add Emrebener/Sublime-Skills --skill ss-sdd-writing-specsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
13.2 KB, ~3.2k tokens by cl100k_base, as published. Nobody here has run it
Writing Specs
Overview
Render the agreed understanding from the discovery stage into a structured spec document. No user interaction in this stage — discovery already happened. The coordinator already holds the agreed content; this skill is about how to lay it out on disk.
Core principle: The spec is a contract. It should be specific enough that a competent engineer (or a fresh subagent) can implement it without re-deriving intent from a chat log.
Announce at start: "I'm using the ss-sdd-writing-specs skill to render the spec document."
Hard Gates
- NEVER commit
.sublime-skills/state.json. It is permanently gitignored. Do NOT bypass viagit add -f,--force,git update-index, or any other mechanism. Seestate-schema.md"Git policy" for the full list. - Do NOT introduce new design decisions in this stage. If you find a gap, stop and return to discovery — don't paper over with assumptions.
- Do NOT include implementation steps, code snippets, file paths to be created, or task lists. Those live in the plan.
- Do NOT use Mermaid, C4, PlantUML, ASCII art, or any other diagram syntax. The spec is prose. If you find yourself wanting a diagram, describe the structure in words or split the description into smaller pieces. The validator catches labeled diagram syntaxes (Mermaid/PlantUML/C4); ASCII art is on honor system — don't sneak it in.
Checklist
- Resolve the feature directory and short name
- Load project context (skip in writers if the coordinator already loaded it — coordinate)
- Write
spec.mdusing the required structure (Spec Structure section below) - Write feature-identifying fields into the existing state file
- Run the inline self-review (Self-Review section below); fix issues inline
- Report the spec path
Step 1: Resolve Feature Directory
Storage layout (fixed):
docs/specs/NNN-<short-name>/
spec.md # this stage writes (user-facing artifact, committed at Stage 7)
.sublime-skills/
state.json # SDD state file (created by preflight at Stage 0; this stage writes feature_id, short_name, work_type, spec_path into it) — gitignored, never committed
Numbering:
NNNis sequential, three digits, zero-padded- Scan existing directories under
docs/specs/for the highest used number; new feature is highest+1 - If no specs exist yet, start at
001
Short name:
- 2-4 kebab-case words from the feature description
- Examples:
user-auth,add-export-csv,fix-payment-timeout
Step 2: Load Project Context
If discovery (Stage 1) already Read these files in this session, you can skip re-Reading — but you MUST still have constitution + ADRs + glossary contents in your working context before writing the spec.
Otherwise, run the discovery script and Read every file it returns a non-null path for before composing the spec:
"${SUBLIME_SKILLS_HOME:?SUBLIME_SKILLS_HOME is not set; see Sublime-Skills README for setup}"/skills/spec-driven-development/framework/discover-context.sh
Required reads when present (skip files the JSON returns as null):
constitution— non-negotiable principles the spec MUST comply with; violations get flagged CRITICAL by ss-sdd-reviewing-specs (Stage 3)- All
adrs— prior decisions you must respect, not re-litigate; silently contradicting a settled ADR is CRITICAL glossary/domain— canonical domain vocabulary; synonym proliferation is HIGH/MEDIUM (vocabulary drift)architecture— situates the feature within existing structurereadme— fallback for high-level project understanding
These reads are load-bearing, not padding — the next stage's auto-review checks the spec against them. A spec written without reading them will fail review.
Empty-context case: if every context field in the JSON comes back null (greenfield project, no bootstrap yet), that's a valid state — proceed without context. Do not halt; do not ask the user to produce files. Note the empty-context state in your final report and move on.
Step 3: Write spec.md
Use the structure in Spec Structure below. Omit any section that doesn't apply — don't leave "N/A" placeholders.
Required sections (in order): Goal, User Stories, Functional Requirements, Success Criteria, Edge Cases, Assumptions, Out-of-Scope.
Optional sections: Key Entities (only if data is involved), Open Questions (only if any remain), References (only if external docs/specs/ADRs are worth linking).
Write atomically. Compose the full spec content, write to <spec_path>.tmp, then mv <spec_path>.tmp <spec_path>. The atomic move prevents a half-written spec.md if the session dies mid-write. Apply the same pattern when editing the spec during the approval gate — never edit-in-place.
Step 4: Write Feature Fields into State
The state file already exists — preflight (Stage 0) wrote the shell. Read the current contents, merge in the feature-identifying fields produced by Stage 1 / this stage, and write back using the atomic pattern (write to .sublime-skills/state.json.tmp, then mv .sublime-skills/state.json.tmp .sublime-skills/state.json). See framework/state-schema.md for the full state schema (and the "Git policy (CRITICAL)" section — state.json is permanently gitignored and must never be committed).
Fields this skill writes:
| Field | Source | Notes |
|---|---|---|
feature_id | This skill (Step 1 dir resolution) | Format: NNN-<short-name>. |
short_name | This skill (Step 1) | Kebab-case. |
work_type | Coordinator's in-memory dict (captured at Stage 1 by ss-sdd-discovering-requirements) | "feature" or "fix". |
spec_path | This skill | docs/specs/<feature_id>/spec.md. |
updated_at | This skill | Touched on every write. |
All other fields (including started_at, current_stage, stages_completed) are owned by other skills or the coordinator — do NOT overwrite them.
Do NOT change current_stage or append to stages_completed here. The coordinator advances the stage and marks spec_written complete after this skill returns. (Avoids racing with the coordinator's stage-advancement logic.)
Do NOT commit spec.md. It stays uncommitted in the working tree. The ss-sdd-choosing-feature-branch skill at Stage 7 batch-commits spec.md alongside plan.md and ADRs. The state file at .sublime-skills/state.json is gitignored and is never committed at any stage.
Step 5: Inline Self-Review
Before reporting back:
5a. Schema validation (automated)
Run the validator script:
"$SUBLIME_SKILLS_HOME/skills/spec-driven-development/framework/validate-spec.sh" docs/specs/NNN-<short-name>/spec.md
If it fails (exit code 1): fix every CRITICAL issue it reports, then re-run. Don't proceed until the script returns PASS. Warnings can be left if they're acceptable for the spec's nature, but address them when easy.
5b. Read with fresh eyes (manual)
The validator catches gross format issues; you check for semantic ones:
- Internal consistency — sections don't contradict each other; FR-### items align with the user stories they support
- Testability — every FR and SC could be evaluated objectively without re-reading the chat
- Scope — focused enough for a single plan; no creeping subsystem sprawl
- Ambiguity — terms that could be interpreted two ways are pinned down or moved to Open Questions
- Vocabulary — uses domain terms from the glossary (if present); doesn't invent synonyms
Fix issues inline. No need to re-review; just fix and move on. (A dedicated ss-sdd-reviewing-specs subagent will pass over this next.)
Step 6: Report
Return to the coordinator. The report must include the validator's PASS line verbatim — the coordinator uses this as proof that validation actually ran and succeeded.
Spec written: docs/specs/NNN-<short-name>/spec.md
Sections present: [list]
Open questions: [count]
State file: feature fields written (feature_id, short_name, work_type, spec_path).
Validator output (last line):
PASS — N warning(s), 0 critical issues
If you cannot produce a PASS line from the validator (the script returned non-zero and you couldn't fix the issues), do NOT claim the spec is written. Report the failure instead with the validator's full output and which CRITICAL issues you couldn't resolve.
The coordinator will re-run the validator before committing — if your reported PASS doesn't match a fresh run, the coordinator aborts the stage. So there's no benefit to faking it.
Spec Structure
# Spec: <Title>
**Feature ID:** NNN-<short-name>
**Created:** YYYY-MM-DD
**Status:** Draft
**Branch:** <branch-name>
## Goal
<One paragraph: what problem this solves and for whom. Use domain vocabulary.>
## User Stories
### Story 1 — <Brief title> (P1)
<Plain-language journey: who, what, why.>
**Why this priority:** <Reason — usually impact or dependency.>
**Independent test:** <How can this story alone be tested as an MVP increment?>
**Acceptance scenarios:**
1. **Given** <state>, **When** <action>, **Then** <outcome>
2. **Given** <state>, **When** <action>, **Then** <outcome>
---
### Story 2 — <Brief title> (P2)
<…same shape as Story 1…>
---
### Story 3 — <Brief title> (P3)
<…same shape as Story 1…>
## Functional Requirements
- **FR-001:** System MUST <capability>. _Stories: US1, US2_
- **FR-002:** Users MUST be able to <action>. _Stories: US1_
- **FR-003:** System MUST <data/behavior>. _Stories: US3_
(Each FR is testable. Each references the stories it supports.)
## Success Criteria
- **SC-001:** <Measurable outcome — time/percent/count/rate.>
- **SC-002:** <Measurable outcome.>
- **SC-003:** <User-experience or business metric.>
(All technology-agnostic, all measurable.)
## Key Entities
(Include only if data is involved. Otherwise omit.)
- **<Entity 1>:** <What it represents, key attributes (conceptual, no DB columns), key relationships.>
- **<Entity 2>:** <…>
## Edge Cases
- <What happens when [boundary condition]?>
- <How does the system handle [error scenario]?>
- <What's the behavior under [unusual load / network / data condition]?>
## Assumptions
- <Things we're treating as given that we should be explicit about.>
- <Defaults adopted from industry standards or project conventions.>
## Out-of-Scope
- <Adjacent feature explicitly deferred.>
- <Capability someone might reasonably expect but isn't included.>
## Open Questions
(Include only if some remain after discovery. Each should be answerable later — they're not blockers.)
- <Question 1>
- <Question 2>
## References
(Include only if external docs/specs/ADRs are worth linking.)
- ADR-NNNN — <title>
- <External doc URL or repo path>
Acceptance Criteria Format Options
Default for "Acceptance scenarios": Given/When/Then. It's compact and readable.
EARS format is allowed when more precision is needed. Use only for FRs or for individual scenarios where ambiguity in the natural-language form is a real risk. Don't mix freely — pick a style per story and stick with it.
EARS templates:
WHEN <event> THEN <system> SHALL <response>(event-driven)IF <precondition> THEN <system> SHALL <response>(conditional)WHILE <state>, <system> SHALL <response>(state-driven)WHERE <feature>, <system> SHALL <response>(ubiquitous)<system> SHALL <response>(unconditional)
If using EARS, mark the story with **Acceptance criteria (EARS):** instead of **Acceptance scenarios:**.
Common Mistakes
| Mistake | Fix |
|---|---|
| Leaving "TBD" or bracketed placeholders | Either fill it in from discovery context or move it to Open Questions |
| Implementation creeping in (file paths, code) | That belongs in the plan. Move it. |
| Multiple stories conflated as one | If two stories have different priorities or different tests, split them |
| Vague success criteria ("fast", "scalable") | Quantify: "p95 < 200ms", "10k concurrent users" |
| Acceptance scenarios that aren't testable | Restate so a tester (or a tester subagent) could verify with a clear pass/fail |
| Domain-noun drift (using "user" then "customer" then "account holder" for the same thing) | Canonical term from glossary; one term across the doc |
Force-adding state.json with git add -f | NEVER. Zero exceptions. |
Editing .sublime-skills/.gitignore mid-pipeline | NEVER. The ignore is permanent. |
Red Flags
- About to start writing the spec without having Read constitution + ADRs (when present) → STOP; that's the failure mode the auto-review (Stage 3) flags as CRITICAL and you'd ship a spec that fails review
- About to use a synonym for a glossary term ("customer" instead of the project's canonical "User") → STOP; vocabulary drift is a review finding
- About to add a Mermaid block → delete
- About to write "the developer should..." → wrong document; that's the plan
- Found a real gap mid-write → stop, return to discovery, don't paper over
- Spec is longer than 600 lines → likely too big; consider decomposition
- About to type
git add -f .sublime-skills/state.json→ STOP - About to edit
.sublime-skills/.gitignore→ STOP
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 1 of the 12 instructions most docs writing skills give in ~3.2k tokens
Counted across 1,637 of the 3,044 authors here whose files we hold, read 2026-08-07
- Announce the skill at starthere, and in 54 of 1637, across 26 files
- Convert legacy doc files before editingin 45 of 1637, across 7 files
- Predict questions readers might askin 42 of 1637, across 4 files
- Generate clarifying questions for initial contextin 42 of 1637, across 3 files
- Create document scaffold with placeholder textin 42 of 1637, across 3 files
- Brainstorm content options for each sectionin 42 of 1637, across 3 files
- Test the document with a fresh context-less instancein 42 of 1637, across 3 files
- Include exact file paths in every taskin 42 of 1637, across 15 files
- Ask interview questions one at a timein 42 of 1637, across 27 files
- Apply surgical edits during refinementin 41 of 1637, across 2 files
- Offer structured workflow or freeformin 40 of 1637, across 1 file
- Ask for document meta-contextin 40 of 1637, across 2 files
Said here and by no other author read
- resolve feature directory and short name
- load project context before writing
- write spec document using required structure
- write feature-identifying fields into state file
- report spec path with validator output
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.