
A practical guide to writing clear, testable requirements that Kiro can turn into better designs and implementation tasks
Kiro uses requirements.md as the starting point for its Spec workflow, and the quality of this file directly affects the work that follows. This guide explains how EARS notation works, how to structure requirements in Kiro, and how to turn vague feature ideas into precise acceptance criteria that developers can review and test.
Table of Contents
- Topic Introduction
- Why EARS Matters in Kiro
- How to Write requirements.md in Kiro
- When to Use Different EARS Patterns
- Top 8 Ways to Write Better requirements.md Files
- Conclusion
Topic Introduction
A feature request such as “add login with Google” is useful as a starting point, but it is not a complete software requirement. It does not define what happens when authentication succeeds, what happens when it fails, what the user sees, or what the system should do when an account already exists.
Kiro’s Spec workflow uses requirements.md, design.md, and tasks.md as its core artifacts. Kiro’s current documentation states that requirements.md contains user stories and acceptance criteria written using EARS notation.
That makes the requirements file more than documentation. It becomes the foundation for the technical design and implementation tasks that follow.
Why EARS Matters in Kiro
- Reduces ambiguity: EARS gives requirements a predictable sentence structure, making vague conditions easier to identify. The notation was specifically created to address common problems in natural-language requirements.
- Improves testability: Clear triggers and expected system responses make it easier to derive acceptance tests from each requirement.
- Guides Kiro: Precise acceptance criteria give Kiro clearer information when producing the design and task artifacts.
- Helps reviewers: Developers, product owners, and technical leads can read the same requirement without learning a formal specification language.
- Limits rework: Clear requirements reduce the chance that design and implementation decisions are based on an incorrect interpretation.
How to Write requirements.md in Kiro
The basic EARS structure is:
While <optional precondition>, when <optional trigger>, the <system> shall <system response>.
EARS uses a small set of patterns for different types of system behavior. The official EARS guidance identifies ubiquitous, state-driven, event-driven, optional feature, unwanted behavior, and complex requirements.
| EARS Pattern | Structure | Best Used For | Example |
|---|---|---|---|
| Ubiquitous | The system shall… | Always-active behavior | The application shall encrypt stored passwords. |
| Event-driven | When…, the system shall… | A specific event | When a user submits valid credentials, the system shall create a session. |
| State-driven | While…, the system shall… | Behavior during a state | While an account is locked, the system shall reject login attempts. |
| Optional feature | Where…, the system shall… | Optional capabilities | Where MFA is enabled, the system shall request a verification code. |
| Unwanted behavior | If…, then the system shall… | Error conditions | If authentication fails, then the system shall display an error message. |
| Complex | While…, when…, the system shall… | Multiple conditions | While MFA is enabled, when login succeeds, the system shall request verification. |
A useful Kiro requirement should normally identify the actor or user story, the condition or trigger, the system, and the expected result.
When to Use Different EARS Patterns
| Situation | EARS Pattern | Recommended Sequence |
|---|---|---|
| Constant rule | Ubiquitous | Define the system behavior first |
| User action | Event-driven | Identify the event, then response |
| System state | State-driven | Define the state, then behavior |
| Optional capability | Optional feature | Identify feature availability first |
| Failure scenario | Unwanted behavior | Define failure trigger and response |
| Multiple conditions | Complex | Combine conditions only when necessary |
EARS is intentionally lightweight. It should make requirements easier to understand, not turn every sentence into a complicated specification. The original EARS work describes the approach as a way to constrain natural language while retaining readability.
Top 8 Ways to Write Better requirements.md Files
1. Start With the User Story
- Name the user: State who needs the capability.
- Define the goal: Explain what the user wants to accomplish.
- State the reason: Capture why the capability is required.
- Keep it focused: Give each user story one clear objective.
- Avoid implementation: Do not describe database tables or code structure in the user story.
A simple format is:
As a [user], I want [capability], so that [outcome].
For example:
As a registered user, I want to sign in with Google, so that I can access my account without creating another password.
2. Convert Behavior Into EARS
- Find triggers: Look for actions such as submit, upload, select, delete, or authenticate.
- Find states: Identify conditions such as locked, active, offline, or authenticated.
- Define responses: State exactly what the system must do.
- Use SHALL: Keep the system response explicit and testable.
- Avoid assumptions: Do not leave important behavior for the developer to infer.
Weak:
The system should handle failed logins properly.
Better:
If the submitted credentials are invalid, then the authentication service shall reject the login request and return an authentication error.
The second requirement gives Kiro and the development team a much clearer behavior to implement.
3. Make Every Requirement Testable
- Define inputs: Specify the condition that starts the behavior.
- Define outputs: State what the system must produce.
- Define boundaries: Include relevant limits and constraints.
- Avoid vague terms: Remove words such as “quickly,” “properly,” and “user-friendly.”
- Create assertions: Make the expected result something a test can verify.
Instead of:
The dashboard should load quickly.
Use a measurable requirement:
When an authenticated user requests the dashboard, the application shall return the dashboard data within 2 seconds for requests meeting the defined performance test conditions.
4. Separate Normal and Failure Behavior
- Cover success: Define the expected behavior when conditions are valid.
- Cover failure: Define what happens when an operation cannot complete.
- Cover invalid input: State how malformed or unsupported input is handled.
- Cover permissions: Define behavior for unauthorized actions.
- Cover recovery: State what happens when recovery is possible.
For a payment feature, for example:
When a valid payment is authorized, the payment service shall record the transaction as successful.
If payment authorization fails, then the payment service shall mark the transaction as failed and return the payment failure status.
5. Keep One Behavior Per Requirement
- Limit scope: Avoid combining unrelated behaviors.
- Use clear clauses: Keep each requirement focused on one outcome.
- Split conditions: Create separate requirements when behavior differs.
- Simplify testing: Make each acceptance criterion independently verifiable.
- Avoid long sentences: Multiple clauses should be used only when they describe one related behavior.
EARS permits multiple responses when they belong to the same requirement, but unnecessary complexity makes requirements harder to review.
6. Write Requirements for Kiro and Humans
- Use plain language: Keep technical terms necessary and defined.
- Name systems: Identify the component responsible for the behavior.
- State dependencies: Mention external systems when they affect behavior.
- Avoid hidden context: Put important assumptions into the requirement.
- Review manually: Treat generated requirements as drafts that need engineering review.
Kiro’s current documentation allows developers to edit generated requirements.md directly and then synchronize the resulting files with the rest of the Spec workflow.
7. Use a Consistent requirements.md Structure
A practical structure for a Kiro Spec can look like this:
# Requirements
## User Story
As a customer, I want to reset my password
so that I can regain access to my account.
## Acceptance Criteria
### Requirement 1: Request password reset
WHEN a registered user submits a valid email address,
the authentication service SHALL create a password reset request
and send a reset email.
### Requirement 2: Invalid email
IF a user submits an email address that is not registered,
then the authentication service SHALL return a generic response
without revealing whether the account exists.
### Requirement 3: Expired token
WHEN a user submits an expired reset token,
the authentication service SHALL reject the request
and instruct the user to request a new reset link.
- Use headings: Make requirements easy to locate.
- Group behavior: Keep related acceptance criteria together.
- Number requirements: Give each requirement a stable reference.
- Keep wording consistent: Use the same terminology throughout.
- Review dependencies: Make external system assumptions explicit.
8. Review requirements Before Design
- Check completeness: Confirm normal and failure paths are covered.
- Check consistency: Make sure requirements do not conflict.
- Check terminology: Use one name for each system concept.
- Check testability: Ask whether every requirement can become a test.
- Check scope: Remove requirements that do not belong to the feature.
Kiro’s Spec workflow moves from requirements to design and then to implementation tasks. Reviewing requirements.md before proceeding therefore gives the team an opportunity to correct the source information before it affects later artifacts.
A Practical EARS Checklist for Kiro
| Check | Question |
|---|---|
| Actor | Is the user or initiating system clear? |
| Trigger | Is the event clearly defined? |
| Condition | Are required states or preconditions specified? |
| System | Is the responsible system identified? |
| Response | Is the expected behavior explicit? |
| Failure | Are important error cases covered? |
| Testability | Can the requirement become an acceptance test? |
| Scope | Does the requirement belong to this feature? |
| Consistency | Are the same terms used throughout? |
| Traceability | Can the requirement be connected to a design or task? |
Conclusion
A good requirements.md file gives Kiro clear behavior to work from instead of leaving important decisions to interpretation. Use EARS to define conditions, triggers, system responses, and failure behavior, then review the requirements before moving into design and implementation. For help applying structured AI development workflows to AWS projects, contact Signiance Technologies.
