requirements.md is the functional specification of a spec bundle: user roles, numbered functional requirements (FR-001) with EARS+ acceptance criteria, non-functional requirements (NFR-001) with measurable targets, and concise data and integration requirements. It is technology-neutral by rule and is the file every task, test, and pull request traces back to.
A vague brief says "the kitchen should be nice". A usable one says "the oven door, fully open, must clear the island by 90 cm". Requirements in EARS+ form are the second kind: WHEN this happens, the system SHALL do that. Each line is a test the builder can run before handing over the keys - and an AI agent cannot "interpret" it two different ways on two different days.
Why requirements are a contract, not a wish list
Coding agents fail on unstated assumptions, not on syntax. "Handle payments reliably" leaves the retry policy, the idempotency window, and the failure path to the model's imagination. requirements.md removes the imagination: each behaviour is a numbered, testable statement with the actor, the trigger, and the response spelled out - including the unwanted behaviours (IF … THEN) that PRDs habitually omit.
- Numbered IDs (
FR-001,NFR-001) give tasks, tests, and pull requests something to cite. - Technology-neutral - the ORM, the framework, and the queue belong in solution.md; requirements must not prescribe them.
- Bounded by the constitution - a requirement that contradicts constitution.md is rejected at review.
Where it lives and when it is written
| Workflow | Path | Shape | Written at |
|---|---|---|---|
| MySpec greenfield | specs/<bundle>/requirements.md | Full specification (FR / NFR) | Stage 3, after the constitution; collect (clarification loop) → generate → review |
| MySpec brownfield | specs/<change>/requirements.md | Requirements Delta (AR / BR / CR) | Stage 3, after the proposal; generate → review |
| Spec Kit | - the same job is done by spec.md | User stories + FR-/SC- | specify stage |
| OpenSpec | - one delta spec.md per capability | ADDED / MODIFIED / REMOVED | specs stage |
The greenfield collect substage is a clarification loop: the Business-Analyst prompt keeps asking focused multiple-choice questions (up to six rounds) until the list of requirements is complete, rather than guessing its way to a draft.
Structure of the greenfield file
# Requirements Specification: [Project Name]
## Overview
## User Roles
- Role 1: Description
## Functional Requirements
### FR-001: [Feature Name]
**Description:** What the system must do.
**User Role:** Which role(s) this applies to.
**Acceptance Criteria:**
- AC1: WHEN [event] THEN the system SHALL [response]
## Non-Functional Requirements
### NFR-001: [Category - e.g. Performance]
**Description:** What quality attribute must be met.
**Target:** Measurable target (e.g. "p95 response time < 200 ms")
**Priority:** High / Medium / Low
## Requirement Diagrams (Mermaid requirementDiagram, FR and NFR groups)
## Data Requirements (max 5 bullets)
## Integration Requirements (max 5 bullets) - Functional Requirements - each
FR-NNNhas a Description, the User Role it serves, and acceptance criteria in EARS+ form. - Non-Functional Requirements - each
NFR-NNNhas a measurable Target and a Priority; a target you cannot measure is not a requirement. - Requirement Diagrams - Mermaid
requirementDiagramblocks, one for FRs and one for NFRs, generated from the entries above (see section 05). - Data & Integration Requirements - at most five bullets each: entities and ownership, retention / privacy, fields needing encryption; external systems, exchange formats, authentication mechanism. Omitted entirely when they do not apply.
Writing acceptance criteria in EARS+
EARS (Easy Approach to Requirements Syntax, from Rolls-Royce) fixes the clause order and the modal verb so a sentence has one reading. EARS+ nests those patterns inside Agile acceptance criteria. Every AC in a MySpec bundle uses one of these shapes:
| Pattern | Template |
|---|---|
| Simple Event | WHEN <event> THEN <system> SHALL <response> |
| Event with Condition | WHEN <event> AND <condition> THEN <system> SHALL <response> |
| State-based | WHILE <state> THEN <system> SHALL <response> |
| Error Handling | IF <pre-condition> THEN <system> SHALL <response> |
| Conditional Event | IF <pre-condition> WHEN <event> THEN <system> SHALL <response> |
### FR-001: User Authentication
**Description:** Authenticated access to the application.
**User Role:** Registered user.
**Acceptance Criteria:**
- WHEN valid credentials are submitted THEN the system SHALL grant access and redirect to the dashboard
- IF invalid credentials are entered THEN the system SHALL display "Invalid username or password"
- WHEN 5 failed attempts occur within 15 minutes THEN the system SHALL lock the account for 30 minutes
### FR-002: Product Search
**Acceptance Criteria:**
- WHEN a search query is submitted THEN the system SHALL return matching products within 2 seconds
- WHEN no results are found THEN the system SHALL display "No products found" AND suggest related categories
- WHERE autocomplete is enabled THEN the system SHALL show suggestions after 3 characters are typed
### NFR-001: Performance
**Target:** Page loads within 3 seconds on standard broadband; 1000 concurrent users without degradation.
**Priority:** High
**Acceptance Criteria:**
- WHEN server load exceeds 80% THEN the system SHALL enable request queuing Full grammar, the six base EARS patterns, and do's and don'ts: EARS Syntax Cheatsheet →
Requirement diagrams
The generator adds a ## Requirement Diagrams section after the NFRs: one Mermaid requirementDiagram for functional requirements (FR_001 nodes with verifymethod: test when they have acceptance criteria, linked by contains / derives / refines) and one for non-functional requirements (performanceRequirement or designConstraint nodes carrying the Target and Priority, linked to the FRs they constrain). Diagrams are capped at 20 nodes so they stay readable.
```mermaid
requirementDiagram
functionalRequirement FR_001 {
id: "FR-001"
text: "Authenticated access to the application"
risk: high
verifymethod: test
}
performanceRequirement NFR_001 {
id: "NFR-001"
text: "p95 page load < 3 s at 1000 concurrent users"
risk: high
verifymethod: test
}
NFR_001 - refines -> FR_001
``` The Requirements Delta (AR / BR / CR)
For an existing codebase you do not re-specify the product; you specify the change. The MySpec brownfield workflow writes a # Requirements Delta grouped by impacted module, where every entry carries exactly one of three prefixes:
- AR-NNN - Add Requirement. A brand-new requirement, shaped exactly like a greenfield FR (Description, User Role, EARS+ ACs).
- BR-NNN - Remove Requirement. No acceptance criteria; a Description of why it goes and a
Reference: file:linepointing at the code or comment that describes the original behaviour - a file the agent actually read. - CR-NNN - Change Requirement. Each changed AC is reproduced
~~struck through~~immediately above its replacement; unchanged ACs are not repeated.
# Requirements Delta: [Project Name]
## Overview
## Impacted User Roles
- Admin, End user
## Authentication ← one section per impacted module
### AR-001: Token refresh endpoint
**Description:** Exchange a valid refresh token for a new access token.
**User Role:** End user.
**Acceptance Criteria:**
- AC1: WHEN a valid, unexpired refresh token is submitted THEN the system SHALL return a new 15-minute access token
- AC2: IF the refresh token is expired or revoked THEN the system SHALL return 401 and require re-login
### BR-001: Legacy session cookie
**Description:** The unsigned session cookie is superseded by bearer tokens.
**Reference:** src/auth/session.ts:42
### CR-001: Suspended Account Handling
**Description:** Suspended accounts must now be rejected at the auth middleware, not only at login.
**User Role:** Admin, End user.
**Acceptance Criteria:**
- ~~AC1: WHEN a suspended user logs in THEN the system SHALL reject the login~~
- AC2: WHEN any authenticated request arrives from a suspended account THEN the system SHALL reject it with 403 Numbering restarts per module (AR-001, BR-001, CR-001 can all live under the same heading), and the module names must be the ones the proposal's Technical Solution used - never invented here.
Authoring and review rules
- Every FR has testable acceptance criteria in an EARS+ pattern; every NFR has a measurable target.
- Requirements describe what, in technology-neutral language, and do not contradict the constitution.
- High-impact requirements only; Data and Integration sections stay within five bullets.
- Delta entries use exactly one AR / BR / CR prefix; BR references point at a real
file:line.
- "Should", "could", "may", passive voice, or universal quantifiers ("all", "any") in a criterion.
- Architecture or stack choices smuggled into requirements ("use Redis for the cache").
- A CR that describes the change in prose instead of showing the struck-through old criterion.
- A metadata footer, or a Requirement Diagram that introduces IDs not defined above it.
How the rest of the bundle uses it
- solution.md must provide a design for every FR and map every measurable NFR to a Success Criteria row.
- tasks.md gives every requirement at least one task and lists the IDs on each task's
_Requirements:_line; its QA Verification milestone derives one verification task per FR from the acceptance criteria, negativeIF … THENpaths included. - Pull requests cite the IDs ("Satisfies FR-001, FR-002"), so reviewers check a diff against a sentence, not against a hunch.
- Through the MCP server, an agent reads the file with
read_spec_filebefore implementing a task and can propose amendments withupdate_spec_fileas a new, reviewable revision.
Related spec files
Project vision, core principles, and the MUST / MUST NOT constraints every later file has to obey.
User roles, FR-/NFR- requirements with EARS+ acceptance criteria; a coded AR-/BR-/CR- delta for brownfield changes.
Architecture, modules, data model, and API design with Mermaid flowchart, ER and sequence diagrams - plus C4 diagrams when your organisation enables them.
Ordered, sized implementation tasks grouped into milestones, traced back to requirement IDs.
Why a brownfield change is needed, what changes, the technical solution, and its impact on existing code.
Spec Kit's prioritised user stories and success criteria, or OpenSpec's ADDED / MODIFIED / REMOVED / RENAMED requirement deltas.
Spec Kit's technical plan: technical context, constitution gates, architecture, data model, and key decisions.
OpenSpec's optional context, goals / non-goals, decisions, and risks for a change.
Workflows that write it
The default four-file bundle: interview → constitution → requirements → solution → tasks.
GitHub Spec Kit's feature-scoped flow: interview → constitution → specify → plan → tasks.
OpenSpec's change-proposal flow: explore → proposal → delta specs → design → tasks.
Let the AI Architect write it for you
MySpec interviews you, then drafts every spec file with collect → generate → review gates. Free during Open Beta.