DEV Community

Cover image for EARS Notation, Explained: The Requirements Syntax Behind Every AI Spec
Nico Acosta for BrainGrid

Posted on • Originally published at braingrid.ai

EARS Notation, Explained: The Requirements Syntax Behind Every AI Spec

A requirements syntax invented in 2009 for jet engine software is quietly becoming the house style for AI coding tools. It was designed for a room full of engineers arguing over a spec. Its best audience turned out to be a machine that never argues.

EARS notation, short for the Easy Approach to Requirements Syntax, came out of Rolls-Royce when Alistair Mavin and colleagues got tired of aerospace requirements that read like legal fog. The 2009 IEEE paper has been cited over 500 times. For fifteen years it lived in systems engineering, the discipline that writes requirements for things that kill people when they fail. Then the AI tools arrived, and EARS started showing up where nobody in 2009 would have predicted: in the specs that coding agents read before they build.

What EARS notation actually is

EARS is a constraint on how you write a requirement, not a new document format or a tool you install. The idea is that most bad requirements are bad in the same few ways, so you give authors a small set of sentence templates that make the common mistakes impossible. Every EARS requirement follows the same clause order:

While <precondition>, when <trigger>, the <system> shall <response>.

That is the whole grammar. The clauses always appear in that order, most are optional, and the word "shall" carries the actual behavior. From that one skeleton, five patterns cover almost everything you need to say.

A ubiquitous requirement is always true, no condition attached: "The system shall encrypt all stored passwords." An event-driven requirement fires on a trigger: "When a user submits the signup form, the system shall send a verification email." A state-driven requirement holds while something is true: "While a payment is processing, the system shall disable the submit button." An unwanted-behavior requirement handles the sad path, the one everyone forgets: "If the payment provider returns an error, then the system shall display the failure reason and preserve the cart." And an optional-feature requirement scopes to a configuration: "Where two-factor authentication is enabled, the system shall require a code on login."

Read those back. Notice what the template forced you to do. You named the exact trigger, the exact state, the exact system, and the exact response. There is no room for "the app should probably handle errors gracefully," because the grammar has no slot for "probably" or "gracefully." That constraint is the entire point.

The reframe: it was built for humans, it pays off with agents

Here is the hypothesis this post rests on. EARS was designed to make requirements unambiguous for a human reader, and it did that job for fifteen years. But its value goes up, not down, the moment the reader is an AI agent, because an agent takes the sentence literally in a way a human colleague never quite does.

When a human reads "the system should handle invalid input," they fill the gap with judgment. They have seen a hundred forms, they know what validation usually means, and they quietly do the reasonable thing. That gap-filling is a feature when the reader is a senior engineer and a liability when the reader is an agent, because the agent also fills the gap, just not necessarily with your version of reasonable. It picks a plausible interpretation, writes code against it, and the demo runs. The mismatch surfaces three weeks later when a real user pastes an emoji into a field you never specified.

The GitHub Spec Kit team is actively debating EARS integration for exactly this reason. The issue puts it plainly: EARS gives authors sentence templates that help them write specifications AI agents can parse more reliably. Amazon's Kiro already generates its acceptance criteria in EARS by default, one of two very different takes on spec-driven development. The tools converging here are not doing it out of nostalgia for a 2009 aerospace standard. They are doing it because a constrained sentence is a better instruction to a literal machine than a fluent paragraph is.

This is the same lesson the AI building community keeps rediscovering in its own words. Steinberger's line that your job is to design the loops that prompt your agents is really a statement about inputs: the loop is only as good as the target you hand it. EARS is one disciplined way to write that target so the agent and the verifier read it the same way.

Vague requirement versus EARS requirement

The difference is easiest to see side by side. Take a single feature, password reset, written the way it usually reaches an agent versus written in EARS.

Vague: "Users should be able to reset their password securely."

EARS: "When a user requests a password reset, the system shall send a reset link to the account email within one minute. The reset link shall expire 30 minutes after issue. When a user opens a valid reset link, the system shall allow a new password to be set. If a user opens an expired or already-used link, then the system shall display 'This link is no longer valid' and offer to send a new one. When a password reset completes, the system shall invalidate all existing sessions for that account."

The first version is a wish. It has one word, "securely," doing an enormous amount of undefined work. The second version is a set of facts you can check. Each "shall" is either true of the running app or it is not, with no room to argue. An agent can build against it, and just as important, a verifier can measure the result against it without asking anyone what "securely" was supposed to mean.

That is the connection most explainers miss. A well-formed EARS requirement is already an acceptance criterion. The syntax that makes intent unambiguous is the same syntax that makes "done" checkable. Write the requirement in EARS and you have not just specified the feature, you have specified the test.

flowchart LR
  A["Vague intent:<br/>'handle errors gracefully'"] --> B["Agent fills the gap<br/>with a guess"]
  B --> C["Demo runs,<br/>looks done"]
  C --> D["Bug surfaces<br/>in production"]
  E["EARS requirement:<br/>'If X, then the system<br/>shall do Y'"] --> F["Agent builds against<br/>a literal target"]
  F --> G["Verifier checks<br/>each 'shall'"]
  G --> H["Done means<br/>verified"]
Enter fullscreen mode Exit fullscreen mode

Where BrainGrid fits

This is the layer BrainGrid works in. You describe a feature in plain language, "let users reset their password," and the Planning Agent turns it into structured requirements with acceptance criteria written to be checkable, the EARS-shaped "when this, the system shall that" statements rather than a paragraph of hope. Then the Builder Agent, working in a cloud sandbox or in your own GitHub repo through Claude Code, Cursor, or Codex, builds against those criteria, and a feature is not done until each one is verified with evidence.

The point is not that you must memorize five patterns and hand-write "shall" sentences all day. Most builders never learn the acronym, and they should not have to. The point is that the discipline EARS encodes, name the trigger, name the system, name the exact response, cover the unwanted path, is exactly the discipline that separates a spec an agent can build reliably from a prompt it has to guess at. BrainGrid captures that intent as a durable record so the plan outlives the chat window, instead of decaying the moment the context fills up.

The trade-off worth naming

EARS is not free, and pretending it is would be dishonest. Constrained syntax is slower to write than a fluent sentence, and it can feel stiff, almost robotic, when you first switch to it. "When a user submits the form, the system shall validate the email field" is less pleasant to read than "the form should check the email." Mavin's own work concedes EARS is a starting discipline, not a universal law: some requirements, particularly complex interacting behaviors, do not fold neatly into one template, and forcing them can make things worse rather than clearer. It is a floor for quality, not a ceiling.

It also does not verify anything on its own. A perfectly formed EARS requirement that nobody checks is still just a nicely worded wish. The syntax makes "done" definable. Something still has to do the defining-versus-reality comparison, which is the verification step, not the writing step. EARS gets you a target the machine can read. It does not pull the trigger.

What this means if you build with agents

If you hand your coding agent one-line prompts and get back plausible code that breaks on the second user, the fix is not a smarter model. It is a less ambiguous instruction. You do not need to adopt EARS formally to get the benefit. You need to write requirements the way EARS forces you to: state the trigger, state the exact behavior, and always write the "if this goes wrong, then the system shall" case, because that is the one your agent will otherwise invent for you.

A requirements syntax built for jet engines turns out to be the right shape for the age of coding agents, for a reason that has nothing to do with aerospace. The literal reader rewards the precise writer. EARS just happens to be the cleanest way anyone has found to write precisely.

FAQ

What is EARS notation?

EARS notation, the Easy Approach to Requirements Syntax, is a structured way to write natural-language requirements using a small set of keywords and a fixed clause order. Developed by Alistair Mavin and colleagues at Rolls-Royce in 2009, it constrains every requirement to the shape "While <precondition>, when <trigger>, the <system> shall <response>," which removes the ambiguity that makes ordinary requirements hard to build and impossible to test cleanly.

What are the five EARS patterns?

The five patterns are ubiquitous (always true: "the system shall encrypt all stored passwords"), event-driven (triggered: "when a user submits the form, the system shall send an email"), state-driven (conditional on a state: "while a payment is processing, the system shall disable the button"), unwanted behavior (error handling: "if the provider returns an error, then the system shall display the failure"), and optional feature (scoped to a configuration: "where 2FA is enabled, the system shall require a code"). Almost every requirement you need to write fits one of these five shapes.

Why is EARS used in spec-driven development and AI coding?

Because an AI agent reads a requirement literally, and a constrained sentence is a more reliable instruction than a fluent paragraph. Tools like Amazon's Kiro generate acceptance criteria in EARS, and the GitHub Spec Kit team is debating adding it, precisely because EARS templates produce specs that agents parse consistently. A well-formed EARS requirement is also already an acceptance criterion, so the same syntax that makes intent unambiguous makes "done" checkable, which is the core of spec-driven development.

What is the difference between EARS notation and acceptance criteria?

They overlap heavily. EARS is a syntax for writing any requirement clearly; an acceptance criterion is a condition that defines when a feature is done. The connection is that a requirement written in EARS is usually already a good acceptance criterion, because "when X, the system shall Y" is both a statement of intent and a checkable test. For the full craft of writing criteria an agent can verify, see how to write acceptance criteria an AI agent can actually verify.

Do I have to use EARS to write good requirements for AI agents?

No. EARS is one disciplined way to hit the target, not the only one. What matters is that your requirement names the exact trigger, the exact system, the exact response, and the unwanted-path behavior, which is precisely the discipline EARS enforces. You can get the same benefit by writing that way without ever learning the acronym, which is essentially what BrainGrid's Planning Agent does for you when it turns a plain-language idea into structured, verifiable criteria.

BrainGrid is the plan-first platform that turns your idea into requirements and acceptance criteria your agent can build and verify against. Try it at braingrid.ai.


Originally published on the BrainGrid blog.

Top comments (0)