How to Scope a Software Build Before Writing Code
When a software build starts without a written scope, the founder, the builders and whoever is paying can each hold a slightly different picture of the product, and the differences surface later as rework. Scoping is the cheap fix: a few hours of writing that forces those pictures into one, before anyone has code to defend.
To keep this concrete, the examples below follow one made-up project: a quote builder for a small residential painting company.
Start with a problem statement, not a feature list
A problem statement names who has the problem, what it costs them today, and how you will know it is solved. Two or three sentences are enough. A useful template:
[Who] currently [does what], which [costs what].
We will know this is solved when [observable change].
For the painting company, that might read: "The owner writes every estimate by hand after a site visit and types it up at night, which eats an evening a week and delays quotes by days. We will know this is solved when a quote can be sent from the customer's driveway before the owner leaves."
Two tests keep the statement honest. First, it should not name a feature. "We need a mobile app" is a solution, and writing it here closes off cheaper options before you have looked at them. Second, the "we will know" line should describe something you could observe, not a feeling. "Quotes go out faster" is weaker than "a quote can be sent before leaving the site."
Name the users and the jobs they need done
List every distinct type of person who will touch the software, then write down what each is trying to get done and in what circumstance. The "jobs to be done" framing from Clayton Christensen and his coauthors in Harvard Business Review is useful here: when people buy a product, they essentially "hire" it to help them do a job, and the circumstances matter more than who the buyer is.
| User | Job | Circumstance | Today's workaround |
|---|---|---|---|
| Owner | Send an accurate quote | In a driveway, phone only, spotty signal | Notebook, then a spreadsheet at night |
| Homeowner | Compare quotes and say yes | Evening, on a phone | Reads a PDF attachment |
| Crew lead | Know exactly what was sold | On site, hands full | Calls the owner |
The circumstance column does a lot of work. "Phone only, spotty signal" turns into real requirements: the tool has to save work without a connection and use controls large enough to hit with a thumb. You would miss both if you only wrote "owner creates quote."
Sort requirements into must, should, could and won't
Once the jobs are clear, list what the software has to do and sort each item. The MoSCoW method, maintained by the Agile Business Consortium, uses four buckets: Must Have (which it describes as the Minimum Usable SubseT), Should Have (important but not vital), Could Have (wanted or desirable but less important) and Won't Have this time. Its guidance is to keep Must Haves to no more than about 60% of the estimated effort and to hold a pool of Could Haves of around 20% as contingency. Note that the split is measured in effort, not in the number of items.
A practical test for a Must: if this item were missing on launch day, would you cancel the launch? If the honest answer is "no, we would ship with a workaround," it is a Should.
For the quote builder:
- Must: build a quote from room measurements and a price list; send it as a link; let the homeowner accept it.
- Should: attach photos to line items; copy a past quote as a starting point.
- Could: color swatches in the quote; a typed signature on acceptance.
- Won't this time: crew scheduling, invoicing, taking payments.
Write the non-goals down
Won't Haves are deferred features. Non-goals are different: they are standing decisions about what the product is not, and they shape design choices long after launch. For the quote builder:
- Not a general customer database. Contact details exist only to send and track quotes.
- Not for commercial bids. The owner does residential work only, and a second pricing model would double the testing.
- One company per account. No franchise or multi-location support.
Give each non-goal a one-line reason. The best non-goals are things a reasonable person might assume are included. Writing them down settles arguments before they start, and it gives you a polite, pre-agreed answer when a new request arrives mid-build.
Define acceptance criteria you can test
Every Must needs acceptance criteria, written before anyone builds it. The Given, When, Then structure from the Gherkin reference is a good default: Given describes the starting context, When describes the event or action, and Then describes the expected outcome.
Feature: Send a quote from the job site
Scenario: Owner sends a quote with no signal
Given the owner has entered measurements for 3 rooms
And the phone has no network connection
When the owner taps "Send quote"
Then the quote is saved on the phone
And it is sent automatically when a connection returns
And the homeowner receives the link within 5 minutes of reconnecting
Good criteria share a few traits. They describe what a person can observe, not how the code works. They cover the unhappy path (no signal, a wrong price, a homeowner who opens the link a month later). And they put numbers on anything that could be argued about. "Fast," "easy" and "secure" are not criteria until they have a threshold attached.
List assumptions and risks separately
An assumption is something you are treating as true without proof. A risk is something that might happen and hurt the project. Keep two lists, because they call for different responses.
For each assumption, write how you could test it cheaply and what changes if it turns out false:
- The owner will measure rooms and type the numbers into a phone. Test: watch the owner price two real site visits using only a phone. If false, the build needs a way to import from a laser measuring tool.
- Homeowners will open a quote link sent by text or email. Test: send links for ten real quotes from the current process and check how many are opened. If few are, attach a PDF copy to every quote as well.
- A price per square foot, with a few add-ons, covers most jobs. Test: re-price last season's quotes using that model and compare. If false, the first version needs itemized pricing per surface.
For risks, a premortem is one of the quickest ways to find them. Gary Klein describes it in Harvard Business Review: the team assumes the project has just failed and writes down plausible reasons why. Because the failure is treated as given, people can name doubts they might keep to themselves in a normal planning meeting. Put the top items in a small table:
| Risk | Likelihood | Impact | Response |
|---|---|---|---|
| Owner stops using it after a week | Medium | High | Pilot on real jobs before building extras |
| Price list is too simple for real jobs | Medium | Medium | Test against last season's quotes first |
| Offline sync loses a quote | Low | High | Write acceptance tests for sync before the UI |
A one-page spec outline
Pull everything above into one page. If it does not fit on one page, you are probably looking at two projects, and the first one should ship before the second is scoped.
- Title, version and owner. One person owns the document and approves changes.
- Problem. Two or three sentences: who, what it costs now, how you will know it is solved.
- Users and jobs. One line per user type: job, circumstance, current workaround.
- Must have. Each item points to its acceptance criteria.
- Should have and could have. Short lists, in priority order.
- Won't have this time. So nobody assumes they are coming in this release.
- Non-goals. Each with a one-line reason.
- Acceptance criteria. Given, When, Then for every Must.
- Assumptions. Each with its cheap test and what changes if it is false.
- Risks. Likelihood, impact and the planned response.
- Open questions. Each with an owner and a date it will be answered by.
Before anyone writes code, send the page to everyone who will build it, pay for it or use it first, and ask one question: "What is missing or wrong?" Fold the answers in, then treat the page as the source of truth. When a change comes up mid-build, it goes into the page first, with the owner's approval, and only then into the code.