Requirements Guidelines¶
A requirement states what the solution must be or do. It does not state how to build it.
Requirements live in the Capability Specification of their capability,
specs/capabilities/NNN-name.md, written from the template in specs/capabilities/README.md.
This guideline covers its requirement sections and its acceptance criteria.
What, Not How¶
- A requirement describes observable properties of the solution, never the solution itself.
- Apply this test: could two different designs satisfy it? If only one can, the requirement prescribes a solution.
- Solutions belong in the specification's Decisions, in design documents, and in ADRs.
- "Users can find a Task by its title" is a requirement. "Use a dropdown with autocomplete" is a solution.
Kinds of Requirements¶
| Section | States | Example |
|---|---|---|
| Functional Requirements | Behavior the capability provides | A Task can be created |
| Non-Functional Requirements | A measurable quality attribute | p95 list latency below 200 ms |
| Technical Requirements | A constraint on the solution space | Runs on the corporate container platform |
| Error Handling | Behavior when something goes wrong | An unknown Task ID is reported, nothing changes |
A section without content says None.
Technical Requirements Are the Exception¶
- Technical requirements restrict the solution space on purpose, so they may name technology or architecture: permitted languages and tools, mandated platforms, interrupt context, target hardware.
- Constrain, do not design. "Services communicate asynchronously" is a constraint; "publish
OrderPlacedto topicorders.v1" is a design decision. - Name who imposes each technical requirement and why. A constraint without a reason cannot be challenged or retired.
- An ADR records a decision taken inside that boundary and cites the requirement as its driver; the requirement does not link to the ADR.
Level of Detail¶
- A functional requirement states a goal of the capability, coarse enough to read as one, and precise enough that an acceptance criterion can decide whether it holds.
- Concrete mappings, such as which input yields which output, go to the Details section as a table; the requirement refers to it.
- A requirement that no acceptance criterion can verify is either too vague or not a requirement.
- A requirement for several variants, such as languages, platforms, or product types, lists each variant in Details, with what differs between them. An empty cell is a gap to resolve, not a default. "For every variant" in prose hides such gaps.
Writing a Good Requirement¶
- Make it atomic: one statement per requirement. An "and" often marks two requirements.
- Make it unambiguous. Replace "fast", "easy", "flexible", and "etc." with something measurable.
- Make it verifiable by at least one acceptance criterion.
- Make it necessary. Trace it to the Context of the capability, and leave out gold plating.
- Quantify every non-functional requirement: metric, target value, load conditions, and how it is measured.
- Keep requirements consistent, within the specification and across capabilities.
Acceptance Criteria¶
- Each acceptance criterion verifies one or more requirements; give test vectors where values matter.
- An automatically verifiable criterion becomes a Gherkin scenario in
test/bdd/features/, named after the criterion. - A criterion that no automated test can check refers to the manual test in
test/manual/that verifies it. - A requirement for every variant is verified for every variant, e.g. by a Scenario Outline over all of them, not by one example.
- Phrase a negative criterion by the capability's own output ("no Motor Status"), not by everything ("no CAN message"); otherwise a later capability refutes it.
Target State, Not Change¶
- A specification describes the current target state of its capability, not a change. It holds no history and no open items.
- Implement a specification only once its status is
Accepted. - When a later capability contradicts an earlier one, correct the earlier specification.
- Refer to a requirement by capability and number, e.g. "capability 003, FR 2", and to an earlier capability instead of repeating it. Links point to earlier capabilities only.
Levels in a Mono-Repository¶
- The root holds the mission statement that every capability builds on, and interfaces that several artifacts share.
- Each artifact holds the Capability Specifications of its own capabilities.
- An artifact's specification links root documents under References.
Neighboring Documents¶
| Document | Answers | Example |
|---|---|---|
| Capability Specification | What must the capability provide, and how is it verified? | Create Task |
| Design document | How do several capabilities fit together? | Communication scheme |
| ADR | Which option was chosen beyond one capability, and why? | Store Tasks in PostgreSQL |
| Guideline | How do we work? | Commits follow Conventional Commits |
Working With AI Assistants¶
- Never invent a requirement. Ask when a need is unclear.
- When code and requirement disagree, stop and say so. Adjust neither silently; change whichever is wrong once its owner has decided.
- Propose a specification as
Draft; the developer sets it toAccepted.
Anti-Patterns¶
- A solution disguised as a requirement ("use a dropdown").
- A compound requirement that hides several statements.
- A vague requirement that cannot fail ("the system is user-friendly").
- Gold plating: a requirement no stakeholder asked for.
- A duplicate: the same need stated twice, which drifts apart over time.
References¶
- ISO/IEC/IEEE 29148:2018 — Systems and software engineering, life cycle processes, requirements engineering
- Software Requirements — Karl Wiegers & Joy Beatty, 3rd ed., 2013
- CPRE Foundation Level Handbook — IREB (online, ireb.org)
Directives¶
- Describe what the solution must be or do, never how to build it; a requirement must be satisfiable by more than one design
- Functional requirements state goals; concrete mappings go to Details, which a requirement refers to
- Every requirement is verified by at least one acceptance criterion
- A requirement for several variants lists each one in Details; an empty cell is a gap, not a default. A requirement for every variant is verified for every variant, not by one example
- Technical requirements may restrict technology and architecture; state the constraint, not the design, and who imposes it and why
- Keep each requirement atomic, unambiguous, verifiable, and necessary
- Quantify every non-functional requirement with metric, target, load conditions, and measurement method
- An automatically verifiable acceptance criterion becomes a Gherkin scenario in
test/bdd/features/; any other refers to a manual test intest/manual/ - Phrase a negative acceptance criterion by the capability's own output
- A specification describes the target state; no history, no open items. Correct an earlier specification that a later one contradicts
- Every section is present; one without content says
None. - Never invent a requirement; ask when a need is unclear. Propose specifications as
Draft - When code and requirement disagree, stop and raise it; never adjust either silently