RequirementsDOMAIN-SPECIFICTEAM-SPECIFICILLUSTRATIVE

Missing Requirements

A brief is defined as much by what it leaves out as by what it says. "Build a payment service" that never mentions currencies, refunds, idempotency, a provider or a ledger is not a short brief — it is a brief with five decisions hidden in it, and the strong learner asks before building.

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

You are given a short brief for something with money in it. How do you find what it does not say, and how do you decide which omissions to ask about and which to assume?

The situation

The brief: "We need a payment service. It should take a payment for an order and record that it was paid. Keep it simple." Two sentences. You could have a first version by tomorrow. Something about the word "simple" makes you nervous and you cannot say what.

The reflex

Build what it says. An endpoint that takes an order id and an amount, calls a provider, stores a row with status paid. Simple was requested; simple was delivered; questions can be asked when they come up.

Why it stalls

The first version stores an amount with no currency, because the brief did not mention one. The day the first order arrives in a different currency, every stored amount is ambiguous and nobody can say which were which.

What the reflex produces — and fails to produce
  • The first version stores an amount with no currency, because the brief did not mention one. The day the first order arrives in a different currency, every stored amount is ambiguous and nobody can say which were which.
  • There is no refund, because refunds were not mentioned — so the first refund is done by hand in the provider's dashboard, and the payment service now disagrees with the provider about what was paid.
  • The endpoint is not idempotent, because the brief said nothing about retries, so the first network hiccup produces a double charge and the "keep it simple" service is now the source of a customer dispute.
  • Every missing decision was made anyway — by the schema, by the provider default, by whichever was quickest — and none of them was made by the person who owns the outcome.
ProblemUnderstandRequirementsConstraintsUnknownsDecompositionSmallest StepModelExperimentObserveDebugLearnIterate

The move

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

  • Read the brief for what it does not say, using the domain as the lens. Anything that handles money has a known set of questions that any payment system must answer: in which currency, with what precision; can money go back (refunds, partial refunds, chargebacks); what happens when the same request arrives twice; through which provider, and what if it changes; where is the record that lets someone reconstruct every movement of money. A brief that omits one of these has not simplified the problem — it has left the decision to whoever builds it.
  • For each omission, decide whether it is a question or an assumption. A question is an omission whose answer changes the design and is not yours to make — currencies, refund policy, the provider. An assumption is an omission you can reasonably fill in *and write down* — "amounts are stored as integer minor units in a single currency for V1" — such that when it turns out wrong, the design changes deliberately.
  • Ask the questions before building, with a recommended answer and the cost of each option, so that the person answering is choosing rather than being interrogated. "I am assuming one currency for V1 and storing the currency code anyway so that adding a second is a data change, not a rebuild — is that right?" is a question that takes a minute to answer.
  • Build the assumptions in a way that keeps them visible: a currency column even when every row says the same thing, a ledger even when it only ever records payments, an idempotency key even when the client never retries. These are not gold-plating; they are the cheapest possible shape of the decisions the brief did not make, placed where they can be changed.

The brief, and what it did not say

The board is the brief after being read for omissions. The known column is short because the brief was; the unknowns column is where the work is, and each entry carries the specific question and the experiment or conversation that settles it. The assumed column is the set of decisions being made deliberately in the absence of an answer — each one written so that it can be wrong on purpose.

"We need a payment service. Keep it simple."
known
  • A payment is taken for an order and recorded as paid.
  • There is exactly one caller in V1: checkout.
assumed
  • ~Single currency in V1, stored as integer minor units with a currency code on every row — wrong the day a customer pays in another currency, and then a data change rather than a rebuild.
  • ~Callers will retry — so every payment request carries an idempotency key from the first version. Not a question for the founder; engineering.
  • ~A ledger of money movements exists from the start, even with one entry type — wrong never; it cannot be reconstructed later.
unknown → question → experiment
  1. ? Refunds?

    becomes Must V1 support returning money to a customer — full, partial, or neither — and if not now, must the record be shaped so that a refund later is an entry rather than a redesign?

    experiment Ask, with the recommendation "not in V1; ledger entries from the start so a refund is a negative entry"; check the provider's test mode for how a refund is represented.

  2. ? Which provider?

    becomes Is there an existing provider relationship or contract, and does the choice constrain hosted checkout, fees, or supported currencies?

    experiment Ask; then a spike creating one test-mode charge through the named provider to see what the integration actually requires.

  3. ? Who is authoritative?

    becomes When our record and the provider's disagree about whether an order was paid, which one wins, and what process reconciles them?

    experiment Force a disagreement in test mode — a charge with no local row — and decide the resolution rule before any production traffic.

Three questions went out with recommendations. The assumptions stayed on the canvas, each with the sentence that would make it wrong.

Asking about the omission, three ways

How the omission is asked decides whether the answer comes back in a minute or a week. The ladder shows one of the three questions at three levels of quality; the best form carries a recommendation and the cost of each option, so the stakeholder is choosing, not researching.

The refund omission
vagueWhat about refunds?
betterDoes V1 of the payment service need to support refunds?
bestI plan to leave refunds out of V1 but record every payment as a ledger entry, so a refund later is a negative entry and not a redesign; the cost is one extra table now. If you expect refunds in the first month, I would build partial refunds now instead. Which is it?

why The best form makes the decision a choice between two named options with a cost each, and it exposes the engineering assumption (the ledger) so the stakeholder can object to it. The vague form makes the stakeholder think about refunds from nothing; the better form invites "no" without telling them what "no" commits them to.

What the assumptions look like in the schema

The cheapest shape of a decision the brief did not make is usually a column. The sketch shows the difference between the brief's version and the version with the omissions filled in — the second is barely longer and every extra line is a decision that can now be changed instead of discovered.

The brief's table, and the table with the omissions filled in
1-- what the brief describes
2payments(id, order_id, amount, status)
3
4-- what the omissions decide, at their cheapest
5payments(
6 id,
7 order_id,
8 idempotency_key UNIQUE, -- repeats: a retry returns the first result
9 amount_minor INTEGER, -- precision: no floating currency
10 currency CHAR(3), -- one value in V1; a data change, not a rebuild
11 provider TEXT, -- which one; the boundary is behind an interface
12 provider_ref TEXT, -- reconciliation: our row against theirs
13 status
14)
15ledger_entries(id, payment_id, kind, amount_minor, currency, created_at)
16 -- kind = 'payment' only, until refunds exist

Nothing here is for scale. Every column is a question the brief did not answer, made explicit at the point where it is cheapest to change.

How to do it

Most important first.

  • Before building anything with money, walk the five questions: currency and precision, reversals, repeats, provider, record. Write each one's status: answered by the brief, assumed by me, or asked (The Unknowns Board).
  • For every assumption, write the sentence that would make it wrong. "One currency" is wrong the day a customer pays in another. If the sentence is plausible within the system's life, store the data that would let you change your mind.
  • Send the questions with recommendations. A question without a recommendation is delegated thinking; a recommendation without the question is an unowned decision.
  • Look at the word "simple" in any brief and ask what it is being used to avoid. It usually marks the decision the writer did not want to make.
  • Compare the brief against a system you know that does the same job. What does the known system have that the brief does not mention? Each one is a candidate omission (The Requirements Nobody States is the design view of the same move).

Worked on a concrete problem

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

  • The payment-service brief, walked. Currency: not mentioned — assumed single currency for V1, stored as minor units with a currency code on every row; the assumption is written and the column exists. Refunds: not mentioned — asked, with the recommendation "not in V1, but the ledger records payments as entries so a refund is a negative entry later, not a redesign". Repeats: not mentioned — assumed retries will happen (they always do) and required an idempotency key on every payment request; no question needed, this is engineering. Provider: not mentioned — asked, because it decides the integration and the fees; recommended one, and a thin boundary so that it can change. Record: not mentioned — assumed a ledger of money movements from the first day, because it cannot be reconstructed later.
  • The questions sent: three, each with a recommendation and a cost. The reply took an afternoon and changed one thing — the founder already had a provider contract, which removed a question and added a constraint. The assumptions stayed assumptions, written on the canvas, each with the sentence that would make it wrong.
  • What the first version looked like as a result: an endpoint with an idempotency key, a payments table with amount in minor units and a currency code, a ledger table with one entry type so far, a provider module behind an interface with one implementation. Every one of these is a few lines more than the brief's version and every one is the decision the brief did not make, placed where it can be changed.
  • The chat app version of the same move: "add message search, keep it simple" omits which messages a user may search (only their own conversations?), whether deleted messages are searchable, and whether search is over content or also attachments. The first omission is a question — it is about privacy and the founder owns it; the other two are assumptions written down with the sentence that would make each wrong.

How you know it worked

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

  • The brief has been annotated with what it does not say, and every omission has a status: answered, assumed, or asked.
  • Each assumption has a sentence beside it that would make it wrong, and the data that would let you change your mind is stored.
  • The questions sent each carried a recommendation and a cost, and at least one answer changed the plan.
  • The first version has a currency code, an idempotency key and a ledger, and none of them took more than an hour.

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
  • ?What does every system of this kind have to decide — and which of those decisions does this brief not mention?
  • ?For each omission: is this a question whose answer is not mine, or an assumption I can make and write down?
  • ?What sentence would make this assumption wrong, and is the data stored so that I could change my mind?
  • ?What is the word "simple" in this brief being used to avoid deciding?

What can go wrong

How the move itself fails
  • The five questions become fifty. Every domain has a list of what a brief usually omits; the move is to walk the short list that changes the design, not to write a questionnaire that delays the reply by a week.
  • Every omission is escalated as a question. Idempotency is not the founder's decision; asking them about it is delegating engineering upward, and it trains them to write shorter briefs.
  • Assumptions are made and not written. "One currency" lived in the engineer's head; the schema has an amount and no code; the assumption is now indistinguishable from an oversight.
  • The move is applied to a brief that was complete. A brief from a team that has shipped three payment services may say "simple" and mean it; asking the five questions of them wastes the afternoon they were saving you.
What the move costs
  • Asking before building delays the first version by the time it takes to get a reply; against a stakeholder who wanted it tomorrow, that delay has to be defended.
  • A currency column, a ledger and an idempotency key are more schema than the brief asked for, and someone will call it over-engineering. The defence is that each is the cheapest form of a decision that cannot be retrofitted.
  • Recommending an answer with each question exposes your judgment to the stakeholder; a bare question would have been safer and less useful.
Misreads
  • "So a short brief means the writer was careless." Usually it means they did not know the domain has these questions. The move is to bring the questions, not to blame the brief.
  • "Assume everything and move fast." Assumptions are for omissions whose answer you can reasonably fill in. Refund policy and provider choice are not those; assuming them is making product decisions at the keyboard.
  • "This is about payments." Payments is the case where omissions cost most. The move — what does every system of this kind decide, and which decisions did the brief skip — applies to a search feature, an upload service or an analytics dashboard; the list of usual omissions is just different.

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.

  • DOMAIN-SPECIFICThe five questions — currency, reversals, repeats, provider, record — are the payments list; a file-upload brief omits size limits, resumability, virus scanning and retention; a search brief omits scope, deleted items and ranking. The move is the same; the list is the domain's.
  • TEAM-SPECIFICFrom a founder who has never built payments, "keep it simple" hides decisions they do not know exist and the questions are a service; from a team that has shipped three payment services, the same words may be a complete brief and the questions are noise — read who wrote it.
  • ILLUSTRATIVEThe two-sentence brief, the afternoon reply and the provider contract are invented; the five questions any payment system must answer are not.

Where the depth lives

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

Securityaudit-logs
Further
  • The practice track's §141 challenge is this brief; the strong answer is the list of questions before the code.