Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Clarifying Requirements and Acceptance Criteria for a Booking Service

Hello. This course starts with a baseline mission: taking a backend brief from an empty repository to a working service. Before you design packages or write Go, the first task is to establish what the service must actually do. That is a practical engineering skill: unclear requirements can produce perfectly functioning code that implements the wrong behavior.

In this lesson, you’ll work from a deliberately incomplete booking-service brief. Your aim is not to resolve every uncertainty yourself. It is to identify consequential ambiguities, turn answers into observable acceptance criteria, and keep unconfirmed decisions visible. Allow about 40 minutes, including a short independent first pass.


The mission brief: read before looking for a solution

A team needs a service for reserving shared rooms. A client provides a customer identifier, a room identifier, and a start and end time to create a booking. Clients can retrieve a booking by its identifier. The service should not accept clashing reservations for the same room. Requests should be quick, and clients may retry when they do not receive a response.

The first demonstrable version may keep bookings in memory. Later versions will use a database and may run as multiple service instances. The team also expects to add cancellation eventually.

Attempt first — 8 minutes. In your own notes, copy phrases from the brief that permit more than one reasonable interpretation. For each, record the question you would ask and what observable behavior would differ depending on the answer. Do not ask AI to elaborate the brief yet. Exact Go API documentation would not help with this task; the missing information is about the product’s behavior.

Keep your notes. The discussion below is a way to inspect your reasoning, not an answer key to copy.


Separate what is stated from what is merely plausible

The brief establishes two capabilities for the first version: create a booking and retrieve one by identifier. It also expresses an intent to prevent clashes. It does not establish, for example, whether a booking ending at 10:00 clashes with one starting at 10:00, what a retry should return, or which time zone a submitted time uses. Each of those choices changes behavior that a client could observe.

A useful distinction is:

  • Stated requirement: “Clients can retrieve a booking by its identifier.”
  • Open question: “What should retrieval return when the identifier does not exist?”
  • Proposed assumption: “Until clarified, treat an unknown identifier as not found.”
  • Confirmed acceptance criterion: An agreed, observable condition against which the service can be evaluated.

Do not promote the proposed assumption to a confirmed criterion merely because it seems conventional. In a blank-repository build, that promotion often happens invisibly: you choose a handler response, write a test for it, and the test makes an unsupported product decision look authoritative.

The same discipline applies to scope. “Add cancellation eventually” is a reason to ask whether cancellation belongs in the first demonstration; it is not permission to design a full cancellation workflow now. “May run as multiple service instances later” matters greatly to future correctness, but it does not, by itself, specify that the in-memory version must coordinate reservations across processes. If that distinction affects sign-off, make it explicit.

Atlassian’s A Guide to Agile Requirements Documentation offers a compact way to keep these categories visible.

A Guide To Agile Requirements Documentation - Inside Atlassian

Read the “Requirements on-a-page” outline for a lightweight place to record what you know without pretending the brief is complete.

In “Requirements on-a-page,” read point 4, “Assumptions,” from its explanation. Then read point 7, “Questions,” from open decisions, and point 8, “Not doing,” from scope boundaries. You can skip the other numbered points for now. Notice that an unanswered question, a working assumption, and an exclusion serve different purposes.

For this mission, a page of decisions and open questions is more useful than a long speculative specification. Give each important assumption an owner or a path to confirmation, and revise the page when an answer arrives.


Ask questions that expose different implementations

“Could you clarify bookings?” is hard to answer. A strong question presents the decision that is needed and why it matters: “If one reservation ends exactly when another starts for the same room, should the second be allowed?” That question exposes a boundary rule without proposing a database constraint or a Go function as the solution.

Questions about the brief tend to cluster around actors and inputs, time, conflicts, failure and retries, and release scope. Use those clusters to search your first-pass notes for omissions. For example, the phrase “clients may retry” leaves a consequential uncertainty: after a response is lost, is a repeated create request expected to identify the original booking, create another booking, or report a conflict? Those outcomes are not interchangeable to a client.

The video Requirements Elicitation – What Questions to Ask, from Bridging the Gap - Resources for Business Analysts, demonstrates a way to prepare questions without assuming you already know the answers.

Requirements Elicitation – What Questions to Ask

Watch this short segment to broaden the questions you bring to the booking brief.

Watch question categories. Listen for the “who,” “what,” and “when” prompts. Apply them to the brief’s clients, identifiers, and reservation times; use them to uncover decisions, not to invent extra features.

Prioritize what you uncover. A useful order is:

  1. Correctness or irreversible surprises: What counts as a clash? Can concurrent clients both be told they secured the same room? What does an uncertain retry mean?
  2. Client-visible contract: Which inputs are required, and what happens on invalid input, conflict, or an unknown booking identifier?
  3. Scope and measurable expectations: Is cancellation excluded from the first version? What would “quick” need to mean before it could be assessed?

This is triage, not a claim that every question must be answered before any work starts. If a decision is reversible and low impact, document a temporary assumption. If two answers imply different promises to clients or different correctness guarantees, seek a decision before building around one.

Ask for behavior, not a preferred mechanism. “Must competing requests for the same room and time result in at most one accepted booking?” is a product question. “Should I use a mutex?” selects an implementation approach before the behavioral requirement is settled.


Turn decisions into acceptance criteria

A booking story expresses an intent; acceptance criteria describe conditions under which the delivered behavior satisfies it. A criterion should let another person determine what happened from inputs and observable results, without reading the implementation.

The video What Are User Story Acceptance Criteria?, from BA-EXPERTS - Learn Business Analysis by Example, distinguishes an intent from the conditions that make it complete.

What Are User Story Acceptance Criteria?

Watch how acceptance criteria add behavior rather than simply restating a user story.

In the distinction, focus on why a restatement adds little clarity. In the flight example, notice that both a matching result and a no-match situation need defined behavior. Bring that same attention to successful bookings and rejected requests.

The image below provides a compact mental model: a story can contain several rules, and a rule may need several concrete examples to reveal its boundaries.

A “Story” card sits above several “Rule” cards, with “Example” cards beneath them. For the booking brief, examples make each proposed rule concrete enough to discuss and eventually verify.

Consider the brief’s “no clashing reservations” statement. Repeating it as “the service prevents clashes” does not settle the boundary. Suppose the team confirms that an ending time may equal the next booking’s starting time. You could then record a criterion along these lines:

Given an existing booking for a room from 09:00 to 10:00, a request for that room from 10:00 to 11:00 can be accepted, provided no other booking conflicts.

That is a conditional illustration, not a decision supplied by the brief. A separate example would cover a request that shares part of an existing interval. Another would address simultaneous requests if the first version promises a concurrency guarantee. Examples expose whether people agree on a rule; they do not replace the rule.

The Requirements Engineering Magazine article Strengthening the Requirements Engineering Process supplies a useful final check for proposed criteria.

Strengthening the Requirements Engineering Process – Requirements Engineering Magazine

Read its short verification checklist to test whether your proposed booking criteria are ready to guide implementation.

In “Final Verification Checklist,” start at the paragraph beginning “After applying the various static and test design techniques.” Read the checklist through its last question. Apply its failure, exception, and boundary prompts to the create-booking behavior. Stop before the discussion following the checklist.

For a first slice, look for at least a successful create and retrieval, a rejected invalid request, a conflicting reservation, and an unknown identifier. Where the expected result remains unsettled, label it open rather than quietly filling it in. You are extracting acceptance criteria and identifying which criteria still require a decision.


The handoff to implementation

Your output from this lesson should be a small, usable requirements record, not code. It should preserve the original brief, identify high-impact questions, distinguish confirmed decisions from temporary assumptions, and state observable criteria wherever the behavior is settled. Include an explicit not doing yet section so “eventually” does not become an accidental first-release commitment.

Before handing that record to an implementation effort, check one final boundary: can someone read each proposed criterion and tell whether a running service passes it, without asking which Go packages, HTTP status codes, or database features you intend to use? If not, either the behavior is still ambiguous or the criterion is describing implementation rather than acceptance.


You’ve practiced the first move in an independent backend build: resist converting vague language into invisible design decisions. Preserve uncertainty, ask questions that distinguish outcomes, and express confirmed behavior in examples that can be checked. In the next lesson, you’ll use those decisions and clearly labeled assumptions to draft the booking service’s first API contract and domain sketch—still before committing to implementation.

Can't find a good explanation? Sign up and we'll make it for you

Sign up