Product and Requirements
Clarifying Requirements: Resolving Uncertainty Before Code
How to find the statements in a requirement that allow incompatible readings, settle what the sources can settle, and put a precise, consequence-aware…
What this unit gives you
Product discovery helps you find the real need, and product requirements and UX foundations help you describe the behaviour that need calls for. The next step, still before any code, is to work out which statements admit incompatible interpretations, what can be established from existing sources, and which decisions belong to the product owner.
A specification records the expected behaviour and the conditions under which it holds. Clarification removes one specific unknown: you find a source, investigate the code or documentation, or ask the person who has the authority to decide. The goal is neither to guess nor to turn every task into a long questionnaire. It is to pin down whatever could change behaviour, access, scope or risk.
Six kinds of statement
In product requirements and UX foundations, labels show what a statement rests on: an observation, a testimony, an inference, an assumption or a decision. Here we look at the same statement from another angle: what exactly needs to be confirmed or decided. In the text of a real task these kinds are usually mixed together.
| Kind | Example | What to do |
|---|---|---|
| Need | "Customers don't know whether they'll be able to cancel an order in time" | Check it against support requests or research; don't generalise a single case to everyone. |
| Behaviour rule | "An order can be cancelled until picking starts" | Check the boundaries, exceptions, roles and the policy currently in force. |
| Fact about the system | "After a cancellation, the payment service issues a refund" | Verify it in the code, configuration, contract or another reliable source. |
| Assumption | "Presumably a manager can cancel any order" | Mark it as unknown and don't let it become a requirement. |
| Product decision | "Should cancellation be allowed after picking has started?" | Go to the owner of the decision if the sources give no answer. |
| Implementation approach | "Store a cancelled flag" |
Don't confuse a technical proposal with the required behaviour; first establish what should happen. |
These are two different classifications: the label from product requirements describes the basis of a statement, while this table describes its content. Keep the important sources, the people responsible and the unresolved questions in a short record, described at the end of this unit.
For any critical statement, also note your level of confidence and the exact source. "We found it in the current policy" is not the same as "this is a preliminary assumption" or "this is what the head of product told us". If there is no source, say so plainly. That way the team will not treat the existing code as proof that this particular behaviour is permitted.
Where uncertainty comes from

A gap. "The user can get a payment refunded" does not say which user, which payment or when. Check the terms, the code and earlier decisions first; if the answer isn't there, ask about the consequence that would change the work.
An ambiguous word or term. "Fast", "active", "new", "support", "visible" and "sync" can all mean different things. If another reading would change the implementation, find a definition or agree on an observable boundary. For example, "the update appears within ten seconds" is clearer than "instantly", but you should not invent such a boundary without the owner and without evidence that it is needed.
An undefined term deserves its own check. "Business day" might mean a calendar day, a day in the client's time zone, or a banking operating day. Find the definition in the current policy or ask the responsible owner for it, then use that single meaning in both the requirement and the checks.
A contradiction. The task lets every employee see a contact, but the privacy policy restricts it to the assigned specialist. Check the dates, the owners, and whether both documents are even talking about the same data; establish which source takes precedence and record how the conflict was resolved. Do not quietly pick whichever rule is more convenient.
Time or state without a boundary. "Change it the same day" does not define the time zone or what happens exactly at the boundary; "the order is active" doesn't say what that changes for delivery or for blocking. Name the start, the end, and the event that moves the system into a different state.
No decision owner. A participant may be able to explain the current code without having any authority to set a new refund policy. Find who is responsible in the team agreement, in Jira or in the role system, and go to the person who is authorised to decide. If no owner is defined, that is a separate governance question, not permission for the developer to decide at random.
From the ordinary scenario to the exceptions that matter

The main scenario (often called the happy path) shows the ordinary route to the result: a customer opens their own order and cancels it before picking starts. But it says nothing about invalid, repeated, late or simultaneous actions.
For any requirement that changes behaviour, think through four groups of situations:
- Input and data: the field is empty, the format is wrong, the value is missing or too large.
- Boundary: the action happens a second before the deadline, exactly at the boundary, or just after it.
- Repetition and timing: the button is pressed twice, the request is retried after a delay, the page is stale, or requests arrive out of order.
- State and access: the order has already shipped, access has been revoked, or the user no longer has the required role.
This is a list to think with, not a demand to build every variant into the product. Keep the cases where a different interpretation would have a visible consequence; drop theoretical exotica that changes neither behaviour nor risk.
For each important scenario, name the observable outcome: what the user will see, what will change in the data, and whether the action is safe to repeat. "Handle the error" is not an outcome. "Show the cancellation status, do not create a second refund, and offer to contact support" is behaviour that someone can actually agree to.
A boundary and a repeated action
The requirement says: "Cancellation is available until the consultation starts." The consultation is booked for 15:00 Oslo time. The page shows the button at 14:59, and the server receives the request at exactly 15:00. Does the action go through? If the appointment was rescheduled, which time defines the boundary, the original or the new one? If the button was pressed twice, could the payment system refund the money twice?
First check whether the time zone and the moment of transition to the "started" state are defined, and whether the payment system handles a retry safely. If the answer is in the policy or a documented API, find it there. If there is no rule, put one question to the owner that covers the boundary, the rescheduling and the repeat: the answer changes both the software's behaviour and the financial expectation.
How to choose what to ask first

Assess each unknown by the consequence of getting it wrong, the likelihood of getting it wrong, the cost of reversing course, and whether it blocks the next piece of work. This is a useful heuristic, not a standard formula.
| Priority | Signal | Example |
|---|---|---|
| High | A mistake affects money, personal data, permissions, an irreversible action or significant rework | Should money be refunded after the order has shipped? |
| Medium | The choice changes one scenario, but it can be isolated and safely postponed | Should the tracking number be shown next to the delivery date? |
| Low | The difference is cosmetic, reversible and does not block an important scenario | Which of two equivalent button labels should we use? |
Start with the unknown that could block the next piece of work or make it wrong. Postpone an irreversible decision only when an interim behaviour has been agreed that nobody will mistake for the final rule. Do not hide access or privacy questions among "assumptions pending clarification".
A good question names the specific rule, offers clear options, briefly shows their consequences and marks the team's recommendation. The options must not nudge the reader towards the answer that suits the author. If a safe standard exists, name it, but don't disguise a missing policy with the word "default".
Poor: "What should we do about cancellation? Please clarify all the requirements."
Better: "The current policy doesn't say whether an order can be cancelled after picking has started. Option A: remove self-service cancellation and suggest contacting support. Option B: allow cancellation but don't refund automatically. This affects the order status and the payment. I recommend not triggering refunds without a separate rule. Who should approve it?"
If you need answers on several related points, group them into one short batch. Don't send a dozen small questions about labels and spacing while it is still unclear who is allowed to perform the action at all.
Risk decides whom to ask, and about what
The four risks introduced in product discovery tell you what evidence to look for and from whom (Marty Cagan, The Four Big Risks):
- Value: does this really solve a meaningful problem for people? You need testimony and behaviour from users, not just the team's assumptions.
- Usability: can a person understand and complete the required action? Watch the scenario being used; Steve Krug reminds us to remove uncertainty from labels and next steps (Don't Make Me Think).
- Feasibility: can the team build and maintain the solution with the systems, data and constraints it has? This is a question for engineering investigation.
- Viability: is the solution compatible with the business, operations, legal obligations and accountability? Authorised owners decide this, not whoever answered fastest in the chat.
Don't reduce the unknown to "can we code this?".
A specialist can check the system but cannot decide on the owner's behalf which behaviour is permitted. And if nobody knows what message a person will see, that too is a requirement that has to be clarified before design and implementation; understandable interaction is covered in product requirements and UX foundations.
Bounds instead of endless clarification
As in a Shape Up pitch, record the problem, the time budget for the work (the appetite), the approach, the risky unknowns (rabbit holes) and what is explicitly out of the change (no-gos); the approach is described in more detail in product requirements and UX foundations (Shape Up, Shape the work). Clarify the unknowns that threaten the agreed scope, not the entire future product. A short request must not silently grow into a specification of the whole product.
Clarification has a working definition of done: the decision is recorded, the owner is known, the key scenario can be described, and the risky boundaries are understood. Anything that can safely be postponed goes into a list of assumptions or into a future task with an owner and a review date. Quietly expanding the goals or adding unconfirmed requirements is not allowed.
How an agent clarifies a request: search first, then ask
When an agent receives a task, it should first look for the answer in the context available to it, rather than asking about things that are already in the task or the repository.
- Read the task, its acceptance criteria, comments, links and the decisions it relies on.
- Find the relevant documents, code, configuration and checks; the code shows the current behaviour, but not necessarily the permitted behaviour.
- Cross-check technical facts against official documentation. Record the source, the decision owner, the assumptions and whatever remains unknown.
- Ask only about unresolved points that will affect behaviour, risk or scope. Once answered, update the requirement and mark any contradicting older record as superseded.
If the name of a state is not defined, the agent first looks for it in the data model and the related API, rather than asking about something it can establish by reading the code. But code can describe the current behaviour rather than the desired one. When it contradicts the policy or the new task, record the conflict and find the owner of the decision.
The planning modes in Codex and Claude Code help you investigate the task and agree the steps first (Codex Plan, Claude Code Plan mode). But their behaviour depends on the version, the interface and the permissions: in the Claude Code terminal, where bypassPermissions is available, that mode can lift the write block during planning. Don't treat the name of a mode as a guarantee; check the current rules of your own environment.
How to record an assumption
If it is safe to proceed, write the interim assumption down explicitly, together with its owner, a review date, and what would have to change if the decision went the other way. Do not assume behaviour that affects access, privacy, money or irreversible actions: those need the owner's decision first.
"Can cancel" does not mean "can refund". "The phone number is hidden in the list" does not mean it cannot be retrieved through the API. A requirement names every required outcome and role instead of relying on the agent's guesswork.
Worked examples
Example 1: "The customer can cancel an order"
The initial request. "Add the ability to cancel an order." This is a direction of work, not yet a rule.
The order in which sources are checked. The agent first reads the task, its criteria, the comments and the related decisions. Next it checks the order page and the current cancellation terms, with their date and owner; the role matrix; the current request path in the code and its tests; and the payment service's documentation on refund status and on how to check safely after a timeout. In a short record it notes, for each source, exactly what that source proves and when it was checked. The code can show what the system does right now, but on its own it does not establish what the policy allows.
What the agent finds. The current policy lets the customer cancel an order until 15:00, warehouse time zone, on the day before dispatch; after that, the customer contacts support. The current code shows the roles and how the request is processed, and the payment service documentation shows how to check refund status. None of these sources says whether the 15:00 boundary is inclusive, which date the deadline is counted from if dispatch is rescheduled, or what to do if the response about the refund is lost. A new rule should not be inferred from whatever the interface happens to allow already.
What to clarify. This affects access to cancellation and money, so the agent asks the owner of orders and finance: "If the dispatch date changes, does the deadline apply to the new confirmed date? Is a request that reaches the server at exactly 15:00 still accepted, or is it handed to support? If the payment service doesn't respond, do we check the status before retrying so we don't create a second refund? Can support change the status without an automatic refund?" The questions name the options and their consequences instead of asking the client to describe the whole feature again.
Decision and requirement. The owner confirms that the deadline is counted from the new confirmed date, in warehouse time; a request the server receives at 15:00 exactly or earlier is accepted, and a later one goes to support; a retry does not create a second refund. After the deadline, support can mark the order as cancelled, but a refund happens only under a separate confirmed rule. The customer sees self-service cancellation only before the deadline; after it, a clear route to support. If the payment service has not reported a result, the system first reconciles the order and refund status and only then offers a safe next action.
State contract and verification. An empty list shows no cancel button. While the request is in progress, the card stays visible, progress is shown and a second press is blocked. After success the status becomes "Cancelled", and the confirmation does not promise a refund without separate confirmation. After an error the record does not disappear: the message explains what happened and offers support or a safe retry; if the server's response was lost, the status is refreshed first. Test the customer and the support role, a request one second before the deadline, exactly at 15:00 and after it, a new dispatch date, a timeout after an accepted request, and a retry with a status check. Compare the UI, the API, the operation log and the payment status; make sure the cancellation does not create a second refund.
Example 2: Documents disagree about who can see a contact
The initial request. "Show the phone number on the client card." Which rule is in force is unclear: a branch document restricts access to the assigned specialist, an old export description allows it for everyone, and the API returns the full number even though the interface masks it.
The order of checks. The agent records the date and owner of each document, then opens the current role matrix, the export configuration, the decision history, the access tests and an actual API response. It separates two statements: "the interface masks the number" describes what is currently visible on screen, while "the role is entitled to see the number" is policy. The code proves the first, not the second. Until the data owner has confirmed which source takes precedence, the conflict stays open, and the full number cannot be considered permitted merely because the API returns it.
Recording the decision. The data owner confirms that the branch rule is in force and the export document is obsolete. We record the owner and the date of the decision, a link to the rule in force, the document it supersedes, the scope of application, and the need to update the export instructions. This is not just an answer in a chat: the team needs to know which text is now the source of truth.
The owner adds detail: the full number is visible to the assigned specialist and to a specifically authorised manager; the absence of an assignment grants no access; for all other roles the number is masked and is not passed through the API or the export. Check this for every role: a mask on screen does not protect the data if the API or the CSV still contains the full number.
| Role or state | Card | API | Export |
|---|---|---|---|
| Assigned specialist | Full number | Full number for this client | Full number, only within the permitted scope |
| Authorised manager | Full number | Full number under the granted permission | Full number, only within the permitted scope |
| Other employee | Masked field | Full value not returned | Full value not exported |
| No assigned specialist | Access not granted automatically | Refusal or missing field, with no leak | Full value not included |
Verification. Sign in with test accounts for each role; repeat a direct API request with the ID of a permitted client and of someone else's client; check the export, a missing assignment, a role change and a revoked permission. Compare the response, the actual export file and the log, and make sure the full number does not leak into an error message or an ordinary log line. The owner confirms the policy; engineering verification confirms that the restriction actually holds on every path.
Example 3: "Improve sign-in"
A poor first question from the agent. "What colour would you like the sign-in button to be?" A request to "improve sign-in" first needs a check of access rules and of how sign-in actually behaves.
What it checks. The agent reads the earlier task about repeated sign-in attempts, the role rules, the current session policy, known defects and the tests. Suppose the documents require that protected data never be revealed after failed authentication, but do not say whether to lock the account after a series of attempts. The logs show repeated sign-ins, but on their own they prove neither that this is an attack nor that the account should be locked.
Questions in order of consequence.
- "After several wrong passwords, should we lock the account, slow down further attempts, or leave the behaviour unchanged? Locking can cut the legitimate owner out of their account; the logs don't define a product rule. This needs a decision from the security or product owner."
- "Does the rule differ for an administrator and an ordinary user?" The current policy says the rule is the same; the agent checks that source before raising this as an unknown.
- "Which shade should the button be?" This is a reversible cosmetic detail, so it can wait.
Decision and the limits of the example. In this invented example the owner decides not to lock the account, but after five failures within 15 minutes to delay the next attempt by two minutes; a neutral message does not reveal whether the account exists. This is a demonstration policy, not a cybersecurity recommendation.
Acceptance criterion. For a single account, the server counts failed attempts in a sliding 15-minute window. After the fifth failed attempt, the next one is accepted no sooner than two minutes later. The response does not reveal whether the entered account exists. A successful sign-in clears the counter. The user sees a neutral message about the delay; the account is not locked.
Verification and open limits. Test the fifth and sixth failed attempts, the window boundary, a retry after the delay, the correct password after the delay, the first failure ageing out of the window, an unknown account, different roles and concurrent requests. It still has to be established where the counter is stored and whether the rule conflicts with the security standards in force. A detailed criterion does not prove the product decision is right: the owner approves the policy, an engineer confirms feasibility. Acceptance criteria and evidence are covered in depth in acceptance criteria and evidence.
A real GitHub discussion: an ambiguous requirement and a testable rewording
The working materials of ASVS v5, the OWASP Application Security Verification Standard, show how an ambiguous requirement gets clarified. Issue #1744, opened on 4 October 2023, asks whether the then-current requirement 5.1.4 about schemas and allowed characters covers free text, such as chat messages, containing the Right-To-Left Override character (RTLO, U+202E), which can visually disguise a file extension (issue #1744, comment on the scope of the check).
The related issue #1640, "5.2.2 sounds like input validation", concerns a vague requirement about sanitisation. On 12 August 2024 someone proposed merging it into 5.1.3 as a duplicate; a comment in #1744 pointed to exactly that early proposal as possibly covering RTLO. After objections, that option was dropped. A later proposal kept 5.2.2 separate and sharpened the rule: process data before passing it into a potentially dangerous context, allow the characters that are safe for that context, and truncate input that is too long (#1744, #1640, early proposal, reference from #1744, refined proposal).
The refined wording went in through PR #2028, linked to #1640 and merged on 26 August 2024; its diff directly confirms the change of wording. Issue #1744 was closed on 3 September with a short comment, "I think that is covered" (closing comment), which does not mention PR #2028. So the link between closing the issue and this change is an inference from the timeline, not a directly confirmed fact. The discussion and the diff prove an editorial clarification, but not a code change or a measured security effect.
Requirement numbers depend on the version: in the stable ASVS 5.0.0 the corresponding requirement is numbered 1.3.3 (recommendation to cite the version, ASVS 5.0.0).
A short record of the requirement and decision
For an important decision, a short record is enough:
- Rule: one behavioural requirement with a condition and a visible outcome.
- Source: a URL, a task, the decision owner or an exact path in the code; add the date it was checked.
- Status: fact, product decision, assumption or open question.
- Owner: who resolves the unknown and who will review the assumption.
- Impact: which users, roles, data, boundaries, integrations or checks will change.
- Next step: find a source, ask a question, update a document, or state the condition under which it is safe to proceed.
If a new answer contradicts an older text, mark the old one as superseded and link to the decision; keep the date, the author and the reason. Don't leave two documents in force with different rules. The full structure of a product requirements document (PRD) is covered in product requirements and UX foundations, and the link between requirements and verification evidence in acceptance criteria and evidence.
What you can now do
You can now check whether the answer already exists in an available source; name an unknown without speculating; put a specific question to the owner, with the consequences of each option; turn the answer into a requirement with a source and testable examples; or safely postpone a bounded assumption with an owner and a review date. The natural next step is to turn the agreed requirement into acceptance criteria and verification evidence.
Sources and further reading
- Marty Cagan, The Four Big Risks, Silicon Valley Product Group, 4 December 2017; accessed 23 September 2026. Used for the categories of value, usability, feasibility and viability risk.
- Steve Krug, Don't Make Me Think, Revisited: A Common Sense Approach to Web (and Mobile) Usability, 3rd edition, New Riders, 2014; author's page checked 23 September 2026. Used for the clarity of the next action and of navigation, not as a summary of the whole book.
- Ryan Singer, Shape Up: Stop Running in Circles and Ship Work that Matters, Basecamp, 2019; the official release of the book was discussed in the REWORK episode of 23 July 2019; online material accessed 23 September 2026. Used for the section on shaping work: the problem, appetite, approach, rabbit holes and no-gos. The material read is not presented as a full reading of the book.
- OpenAI Developers, Run long horizon tasks with Codex, 23 February 2026; Anthropic, Choose a permission mode — Claude Code Docs; checked 26 September 2026.
- OWASP, issue #1640, issue #1744, PR #2028 and ASVS 5.0.0; checked 26 September 2026. The issues provide context and the course of the discussion; the PR shows the change of text, but not its effect on code or security.