RequirementsGENERALTEAM-SPECIFICILLUSTRATIVE

Functional Requirements

A functional requirement says what the system does, for whom, with what observable result. "Manage orders" is not one; "an admin can change an order from paid to shipped and the customer is notified" is. The test is whether you could watch it happen.

The moveWorked exampleNext questions

The situation, the reflex, and why it stalls

Every lesson starts where being stuck starts: someone has a problem, and the first move that comes to mind feels like progress.

The question

How do you write down what the system must do in a form that can be built, tested and argued about — rather than a list of verbs that everyone agrees with and nobody can check?

The situation

The requirements document for the store says: "Product management. Cart functionality. Order processing. Payment integration. User accounts." Five lines, all approved. You start on "order processing" and realise it could mean anything from "an order row exists" to a fulfilment pipeline with returns.

The reflex

Expand each heading into sub-headings. "Order processing: create order, update order, cancel order, view orders." It looks like detail and produces a longer document, and the longer document is signed off faster because it looks more thorough.

Why it stalls

The sub-headings are still verbs without actors or outcomes. "Update order" — who, from what state to what state, and what does anyone see afterwards? The document is longer and the questions are the same.

What the reflex produces — and fails to produce
  • The sub-headings are still verbs without actors or outcomes. "Update order" — who, from what state to what state, and what does anyone see afterwards? The document is longer and the questions are the same.
  • Because nothing is observable, nothing is testable, so the tests get written against the implementation instead of the requirement — and pass by construction.
  • Estimates are impossible. "Cancel order" is an hour if it means a status flag and a week if it means refunding the payment, restocking the items and emailing the customer. The estimate given is whichever the estimator imagined.
  • Disagreements surface in review of the code rather than of the requirement. The reviewer expected cancel to refund; the author did not; both were right about the document.
ProblemUnderstandRequirementsConstraintsUnknownsDecompositionSmallest StepModelExperimentObserveDebugLearnIterate

The move

Precisely enough to apply it to a problem you have never seen — not a slogan.

  • A functional requirement has three parts or it is not one: an actor (who or what triggers it), a behaviour (what the system does), and an observable result (what exists or is visible afterwards that was not before). Rewrite every heading until it has all three. "Order processing" becomes several sentences of the form "when an admin marks a paid order as shipped, the order's status is shipped and the customer receives a shipping email".
  • For each sentence ask: could I watch this happen? If the result is observable — a row, a screen, a message, a status — the requirement can be tested and estimated. If not, the sentence is describing an intention, and it needs a result attached before it counts.
  • Group the sentences by actor and by workflow, not by technical component. A grouping by "frontend / backend / database" is a grouping of the solution; a grouping by "customer buying / admin fulfilling" is a grouping of the problem, and it is the one that survives a change of stack (Decomposition by Capability).
  • Mark the boundary between functional and non-functional explicitly. "Checkout completes" is functional; "checkout completes quickly" is a quality of it, and belongs in Non-Functional Requirements with a measurement attached, not in the same list disguised as a feature.

A heading against a requirement

The pair below is the same intention written twice. The first is what the document said; the second is what could be built and checked. The difference is not length — it is that the second names who, what and what is left behind.

"Cancel order"
The heading
Order processing: create order, update order, cancel order, view orders.
The requirement
When a customer cancels an order that is paid and not yet shipped, the order's status becomes cancelled, the full payment is refunded through the provider, the items return to available stock, and the customer sees a cancellation confirmation. An order that has shipped cannot be cancelled by the customer.

The second sentence can be estimated (it names a refund, a stock change and an email), tested (each result is observable), and argued with (the founder had not decided whether shipped orders are cancellable). The heading could be all of that or a status flag, and two engineers would build different things from it.

Grouping by what the customer is doing

Rewritten requirements group naturally by actor and workflow, and the grouping is a decomposition with the tests already attached. Every leaf below is a sentence someone could watch come true; the parents are the workflows that give the leaves a reason to exist.

Compare this with grouping the same requirements by frontend, backend and database: every leaf would appear three times, and none of the three would be independently observable.

The store's functional requirements, by workflow
What the store does
  • Customer buys
    • Browse and view productstestable A product created by an admin appears in the list and on its own page with the same name, price and stock.
    • Build a carttestable Adding, changing quantity and removing produce the expected items and a total equal to the sum of current prices.
    • Check out and paytestable A successful test-mode payment produces one order with status paid and the prices captured at checkout.
    • See own orderstestable A customer sees their orders with status; another customer's orders are not visible.
  • Admin fulfils
    • Create and edit productstestable A price change is reflected on the product page and in new carts; existing paid orders keep their captured price.
    • Mark orders shippedtestable A paid order marked shipped has status shipped and a tracking email was sent; a cancelled order cannot be marked shipped.
  • Deferred — with reason
    • Cancel a paid order with refundtestable Deferred: needs the refund flow and a returns policy; the observation would be a refunded payment and restored stock.

The deferred branch is in the tree so that it is visible, not so that it is built. Its leaf still carries the observation it would need — that is what makes it a deferred requirement rather than a forgotten one.

One requirement, one example

The fastest check of a functional requirement is a concrete example with values in it. If the example cannot be written, the requirement is not specific enough; if it can, it is the first test case and the first conversation with the stakeholder.

Mark as shipped — the example beside the requirement
1Requirement
2 When an admin marks a paid order as shipped, its status becomes
3 shipped and the customer receives an email with the tracking link.
4
5Example
6 Order #1042 customer: alice@example.test status: paid
7 Admin bob marks #1042 shipped with tracking "RX123"
8 -> #1042 status: shipped, shippedAt set
9 -> email to alice: subject "Your order has shipped", link for RX123
10
11Counter-example (what the requirement forbids)
12 Order #1043 status: cancelled
13 Admin bob marks #1043 shipped
14 -> rejected: "cannot ship a cancelled order"; #1043 unchanged; no email

The counter-example is where the state machine shows up. Nobody wrote "cancelled orders cannot ship" in the document; the example forced the question.

How to do it

Most important first.

  • Take each heading and write "when <actor> <does>, the system <does> and <result is observable>". If you cannot fill the third slot, ask the stakeholder what they would look at to know it worked.
  • Write one concrete example per requirement with real-looking values: "Alice's order #1042, paid, marked shipped by admin Bob; Alice receives an email with the tracking link" (Example-Driven Thinking).
  • Check every requirement for the hidden state it implies. "Mark as shipped" implies an order has a status, that "shipped" is one, and that some transitions are illegal — that is the beginning of Finding the State Machine.
  • Separate what the system does from how well it does it. Move every "quickly", "securely", "reliably" into the non-functional list with a question attached: how quickly, measured where?
  • Hand the rewritten list back to the stakeholder and watch which sentences they argue with. The arguments are the requirements you got wrong; the silence is the ones you got right — or the ones they did not read.

Worked on a concrete problem

The move has to produce something. This is what it produced.

  • "Order processing" rewritten: "When a customer completes checkout with a successful payment, an order exists with the items, quantities and prices as they were at checkout, with status paid, and the customer sees a confirmation with the order number." "When an admin marks a paid order as shipped, its status becomes shipped and the customer is emailed a tracking link." "When a customer cancels an order that is paid but not shipped, its status becomes cancelled, the payment is refunded in full, and the items return to stock." Three sentences; each has an actor, a behaviour and something to look at.
  • The third sentence started an argument. The founder had not thought about refunds; "cancel" in their head meant "the customer changes their mind before paying". So the requirement split in two: cancelling an unpaid checkout (V1, trivial) and cancelling a paid order (deferred, needs the refund flow). The original heading "cancel order" contained both and hid the difference.
  • "Cart functionality" rewritten and grouped by workflow: add an item, change a quantity, remove an item, see the total — each with an observable result. Then the hidden state: a cart belongs to someone, survives something, and expires sometime. Three questions for the stakeholder that "cart functionality" never asked.
  • "Product management" produced the first non-functional requirement by accident: "an admin can upload a product image" is functional; "the image appears on the product page within a second of upload" is not, and moved to the other list with "measured where?" beside it.

How you know it worked

What now exists that did not before, and what question you can now ask.

  • Every requirement names who, what, and what you would look at afterwards — and a tester could write a test from the sentence alone.
  • Estimates for the same requirement from two people land in the same order of magnitude, because they are estimating the same thing.
  • The stakeholder argued with at least one sentence, and the argument was about the product, not about the wording.
  • Words like "quickly", "securely" and "scalable" have left the functional list and appear in the non-functional one with a measurement beside them.

The questions you can now ask

The field this whole domain exists for. After this lesson, these are the questions to put to an unfamiliar problem.

Next questions
  • ?For this requirement: who triggers it, what does the system do, and what could I look at afterwards to know it happened?
  • ?What state does this requirement quietly assume exists — and which transitions between states does it imply are legal?
  • ?Is this sentence about what the system does, or about how well it does it — and if the latter, what is the measurement?
  • ?Which of these sentences would the person who asked for them argue with, and have I shown them?

What can go wrong

How the move itself fails
  • The rewriting becomes a specification ritual: every sentence in a mandated template, every requirement numbered, a tool to manage them. The three parts are the discipline; the template is not.
  • Requirements are written at the level of UI gestures — "the user clicks the blue button" — so that every design change invalidates them. Write what the system does, not which pixel triggers it.
  • The observable result is chosen because it is easy to observe, not because it is what matters. "The API returns 200" is observable and says nothing about whether the order was created.
  • The functional list is treated as finished. Rewriting headings finds the requirements that were implied; it does not find the ones nobody imagined, which is what Requirement Discovery and Missing Requirements are for.
What the move costs
  • Three-part sentences are longer and more numerous than headings; a document of them is harder to skim and easier to argue with, which is the intended trade.
  • Concrete examples date quickly — the example order #1042 refers to a schema that will change — and need maintaining or discarding.
  • Writing a requirement precisely commits you to it; an ambiguous "cancel order" let everyone believe their own version for a few more weeks.
Misreads
  • "So we are writing user stories." The three parts overlap with the story format but the point is the observable result, which most stories omit. A story without a result is a heading with a persona attached.
  • "Functional requirements are the complete behaviour of the system." They are the behaviour someone asked for. The behaviour under failure, repetition and concurrency is mostly discovered, not requested — see Failure Path Second.
  • "If I write them well enough I will not need to talk to anyone." The rewriting is what makes the conversation productive; it does not replace it. The argument the stakeholder starts is the requirement working.

Where this applies

Problem-solving advice is stated as universal far more often than it is. These labels say what each method is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.

  • GENERALActor, behaviour, observable result is the shape of a functional requirement for a store, a compiler or a data pipeline; for a library the actor is the caller and the result is the return value and side effects.
  • TEAM-SPECIFICA solo builder can hold the three parts in their head and skip the writing; a team of three cannot, and a team with a separate product owner needs the sentences written because the arguments happen in writing.
  • ILLUSTRATIVEThe five-line requirements document, the order numbers and the refund argument are invented; the shape of the rewrite is the point.

Where the depth lives

This domain asks the question and hands the answer off by name.