Level 9Lesson 74โฑ๏ธ 45 min

Writing Specs That Don't Lie (EARS)

A spec is only useful if it's precise enough to be checkable. Learn EARS - a simple way to write requirements an agent can't misread

Most Specs Are Too Mushy to Help

"The app should be fast and user-friendly." That's not a spec - it's a wish. Fast how? User-friendly to whom? An agent (or a human) can't build it and can't check it. A good spec has one job: be precise enough that you can tell whether it was met.

The test for any requirement: could two different people read it and agree on whether the finished software satisfies it? If not, it's too mushy - and the agent will fill the fuzziness with a guess (an intent gap).

Functional vs. Non-Functional Requirements

Specs hold two kinds of requirements, and you need both:

Functional requirements (FRs) - what it does

Concrete behaviors. "A user can reset their password via an emailed link." "Tasks can be filtered by status." These are features.

Non-functional requirements (NFRs) - how well it does it

Qualities, not features. Speed, security, accessibility, reliability. "Pages load in under 2 seconds." "All actions are keyboard-accessible." Beginners forget these, and they're where products quietly fail.

EARS: A Simple Recipe for Clear Requirements

EARS (Easy Approach to Requirements Syntax) is a tiny set of sentence templates that force precision. You don't need jargon - just fill in the blanks. The magic is that every EARS sentence has a clear trigger and a clear response, so there's nothing to misread.

The five EARS patterns:

UBIQUITOUS   "The <system> shall <do something>."
             โ†’ always true. "The app shall store tasks in a database."

EVENT        "WHEN <trigger>, the <system> shall <response>."
             โ†’ "WHEN a user submits the form, the app shall save the task."

STATE        "WHILE <in some state>, the <system> shall <response>."
             โ†’ "WHILE a user is logged out, the app shall hide the dashboard."

CONDITIONAL  "IF <condition>, THEN the <system> shall <response>."
             โ†’ "IF the password is wrong, THEN the app shall show an error."

OPTIONAL     "WHERE <feature is included>, the <system> shall <response>."
             โ†’ "WHERE dark mode is enabled, the app shall use dark colors."
Why this works: "shall" + a trigger + a response leaves no room for interpretation. Each sentence makes one checkable claim. You can literally write a test for it.

Mushy vs. EARS - Side by Side

MUSHY                          EARS (checkable)
"Login should work well"   โ†’   WHEN a user enters a valid email and
                               password, the app shall log them in and
                               redirect to the dashboard.

                               IF the email or password is invalid, THEN
                               the app shall show "Invalid credentials" and
                               keep them on the login page.

"Make it secure"           โ†’   The app shall store passwords only as salted
                               hashes, never as plain text.

                               WHILE a user is logged out, the app shall
                               deny access to all /dashboard routes.

Notice the mushy line became four precise requirements. That expansion is the work - it's where you find the decisions you hadn't made yet.

Acceptance Criteria: How You Know It's Done

Each requirement should come with acceptance criteria - the specific, observable conditions that prove it works. These are what tests get written against (a theme you'll see explode in LID two lessons from now).

Requirement: WHEN a user submits a new task, the app shall
             save it and show it at the top of the list.

Acceptance criteria:
  โœ“ The task appears in the list without a page reload.
  โœ“ The task persists after refreshing the page.
  โœ“ Submitting an empty task shows a validation error instead.
Callback to Level 8: good specs are the "right altitude" again - specific enough to check, not so rigid they script every pixel. EARS keeps you in that zone automatically.

Hands-On: Rewrite a Wish as EARS

Hands-on (20 min): Take a vague feature wish - say, "users should be able to manage their profile." Rewrite it as 4-6 EARS requirements using the templates above (mix EVENT, IF/THEN, and at least one NFR like security or speed). Then add 2-3 acceptance criteria to the most important one. Notice how many decisions you're forced to make that the original wish hid. Keep this - it's the seed of your capstone spec.
Lesson 74 Quick Reference
Checkable test

A good requirement lets two people agree on whether the software meets it - otherwise it's a guess waiting to happen

Functional requirement (FR)

What the system does - a concrete behavior or feature

Non-functional requirement (NFR)

How well it does it - speed, security, accessibility, reliability

EARS

Easy Approach to Requirements Syntax - sentence templates with a clear trigger and response

The five EARS patterns

Ubiquitous, Event (WHEN), State (WHILE), Conditional (IF/THEN), Optional (WHERE)

Acceptance criteria

The specific, observable conditions that prove a requirement is met - what tests check

โ† What Is Spec-Driven Development?
Unlocks in ~12 min of reading