| name | writing-specs |
| description | Use when brainstorming has settled requirements in chat and delta specs do not yet exist for the change, or when review-changes returned CRITICAL findings that require revising an existing delta — produces delta specs under docs/specs/changes/{name}/specs/{domain}/spec.md using heading-as-identifier requirements, RFC 2119 language, and Given/When/Then scenarios, with a Change Overview header capturing Why/Impact/Non-goals. |
| metadata | {"tags":["tech:markdown","spec-driven","workflow","spec-authoring"]} |
Writing Specs
Overview
Author requirements as headings with RFC 2119 normative language and BDD scenarios. New changes write delta specs under docs/specs/changes/{name}/specs/{domain}/spec.md. Stable specs (docs/specs/{domain}/spec.md) are only modified by code-review during delta merge.
Violating the letter of the rules is violating the spirit of the rules.
Every requirement MUST have at least one `#### Scenario:` block with Given/When/Then. A requirement without a scenario is not a requirement. Do NOT save a delta spec with scenario-less requirements. Do NOT use "should" or "may" in the requirement statement — use MUST/SHALL/SHOULD/MAY per RFC 2119.
The Iron Law
NO REQUIREMENT WITHOUT A SCENARIO FIRST
When to Use
Always:
- Brainstorming has settled requirements in chat and a delta spec must be written.
- An existing delta needs revision after
review-changes flagged issues.
- A brand-new domain spec is being bootstrapped (rare; still needs a change folder).
Exceptions: none. Stable specs are edited only by code-review.
Format Rules
Requirement identity
### Requirement: <Name>
The system MUST <normative statement>.
#### Scenario: <scenario name>
Given <precondition>
When <action>
Then the system MUST <outcome>
- Heading is
### Requirement: <Name> — exactly three hashes + space + Requirement: + space + name.
- Name is the identifier. Changing the name = RENAMED operation.
- Scenarios use
#### — exactly four hashes. Three hashes or bullets will silently fail validation.
Delta operation sections
A delta spec file (docs/specs/changes/{name}/specs/{domain}/spec.md) declares operations under ## headings:
## ADDED Requirements
### Requirement: <New>
...
## MODIFIED Requirements
### Requirement: <Existing name, unchanged>
<ENTIRE updated requirement body, including ALL scenarios>
## REMOVED Requirements
### Requirement: <Existing>
**Reason**: <why>
**Migration**: <what users/callers should do>
## RENAMED Requirements
- FROM: `<old name>`
TO: `<new name>`
RFC 2119
See references/rfc-2119.md. Summary:
- MUST / SHALL — absolute requirement. Non-compliance = defect.
- MUST NOT / SHALL NOT — absolute prohibition.
- SHOULD / SHOULD NOT — strong recommendation; deviation requires justification.
- MAY / OPTIONAL — truly optional.
Use MUST/SHALL for normative statements in requirements. Avoid mixing SHOULD into hard requirements.
Process
- Confirm settled requirements from the brainstorming conversation. Identify affected domains.
- Create the change folder
docs/specs/changes/{name}/ if it does not exist.
- For each affected domain, create a delta spec at
docs/specs/changes/{name}/specs/{domain}/spec.md using references/templates/delta-spec.md. The primary delta MUST open with a ## Change Overview section capturing Why, Impact, Non-goals, and Rollback. If the change touches multiple domains, include the Change Overview in only one delta (or a top-level docs/specs/changes/{name}/overview.md) and cross-reference.
- For new domains, also create the stub stable spec at
docs/specs/{domain}/spec.md with no requirements yet; the ADDED section of the delta will populate it on merge. Use references/templates/stable-spec.md.
- For MODIFIED operations, copy the ENTIRE existing requirement block (heading + body + all scenarios) from the stable spec, then edit in place. Partial MODIFIED loses detail at merge time.
- For REMOVED operations, include
**Reason**: and **Migration**: lines.
- Announce transition to
review-changes.
Checklist
You MUST work through each of these items and complete them in order:
- Change folder exists at
docs/specs/changes/{name}/.
- Every affected domain has a delta spec file.
- A
## Change Overview section exists capturing Why / Impact / Non-goals / Rollback.
- Every requirement uses
### Requirement: <Name> heading format.
- Every requirement has at least one
#### Scenario: with Given/When/Then.
- RFC 2119 keywords (MUST/SHALL/SHOULD/MAY) used correctly in normative statements.
- MODIFIED sections contain the FULL updated requirement body.
- REMOVED sections include Reason and Migration.
- RENAMED sections use
FROM: ... TO: ... syntax.
- Handoff to
review-changes announced.
Common Rationalizations
| Excuse | Reality |
|---|
| "Scenarios are redundant — the statement is clear" | Scenarios are testable. Statements aren't. Requirements without scenarios fail silently at review. |
| "MODIFIED only changed one line, I'll just include that line" | Partial MODIFIED sections drop detail on merge. ALWAYS copy the entire block. |
| "SHOULD is basically MUST, close enough" | SHOULD permits deviation with justification. MUST does not. Pick one. |
| "Three hashes, four hashes, markdown is forgiving" | #### exactly. Otherwise scenarios are not parsed as scenarios. |
| "I can skip the Migration note — it's obvious" | Another agent (or a future you) will not find it obvious. Write it. |
Red Flags — STOP and Start Over
- Wrote a requirement with no scenario
- Used "should" lowercase in a statement
- MODIFIED block is shorter than the stable block it replaces
- REMOVED entry has no Reason line
- Editing
docs/specs/{domain}/spec.md directly without a delta
- Putting implementation details ("uses bcrypt") in requirements instead of behavior ("MUST hash passwords")
All of these mean: delete the draft section, start with the template.
Anti-Pattern: "I'll add scenarios later during review"
Scenarios are how the requirement gets reviewed. Writing them later means the requirement is unreviewable now, and review-changes will send it back. Add them as you write the statement — they often reveal ambiguity in the statement itself.
Example
Delta spec for add-admin-2fa:
## ADDED Requirements
### Requirement: Admin Two-Factor Authentication
The system MUST require a valid TOTP code from all admin accounts during login.
#### Scenario: Valid TOTP
Given an admin account with TOTP configured
When the admin submits valid credentials and a valid TOTP code
Then the system MUST issue a session token
#### Scenario: Invalid TOTP
Given an admin account with TOTP configured
When the admin submits valid credentials and an invalid TOTP code
Then the system MUST return 401
And the system MUST NOT issue a session token
## MODIFIED Requirements
### Requirement: Session Expiration
The system MUST expire admin sessions after 15 minutes of inactivity.
#### Scenario: Admin idle
Given an admin session with no activity for 15 minutes
When the admin makes a request
Then the system MUST return 401
Verification Checklist
Integration
Terminal state is invoking review-changes automatically. Once the delta is written and the Verification Checklist passes, invoke review-changes WITHOUT asking the user to proceed. This is self-review — no approval gate exists here. Do NOT invoke plan-review, execution, or code-review.
REQUIRED SUB-SKILL: Use review-changes immediately once the delta is written. Do NOT ask the user "should I proceed to review?" — just invoke it.