DEV Community

Cover image for How to scope a software project: a step-by-step guide
Oleksandr Tytarenko
Oleksandr Tytarenko

Posted on Edited on Originally published at discoveryphaseai.com AI-assisted

How to scope a software project: a step-by-step guide

To scope a software project, start from the goals, list the users and what they need, turn that into prioritised requirements, and then write down explicitly what is in, what is out and what comes later. Estimate the in-scope work as a range with its assumptions, and get one decision maker to sign the result. The seven steps below follow that order; the in, out and later list in step 5 is the artifact that does most of the work.

What scope is, and what scope creep is

Scope is the agreed list of what the project will deliver, and just as importantly, what it will not. It is not the same as the requirements: requirements describe what the product must do, while scope sets the boundary of this particular piece of work, usually one release.

Scope creep is what happens without that boundary. The PMI defines it as the uncontrolled expansion of project or product scope without matching changes to time, cost and resources (PMI, Scope and stakeholder management). The key word is uncontrolled: scope can change, and often should, but each change needs a visible decision about what it costs and what moves out.

Scoping well is mostly done during the discovery phase. If you want the wider context, see what a discovery phase is in software development.

Step 1-2: goals and users

Step 1: Write two or three goals with numbers

Everything else is judged against the goals, so start there. A goal says what changes for the business or the user, with a metric, today's value, a target and a date. "Improve onboarding" is not a goal; "cut the time from sign-up to first invoice from 3 days to 1 day by June" is.

Ask the decision maker to rank the goals. When two features compete for the same week, the ranking decides.

Step 2: List the users and what they are trying to do

Name each type of user (and each external system the product talks to) and the main job they need to get done. Then walk through the main journey of each, step by step, and mark where it goes wrong today. Talk to people who will use the product, not only to the people who pay for it.

This step catches the most expensive scope gaps: the admin role nobody mentioned, the approval step that exists only in one manager's head, the data import that has to happen before anyone can use the product at all.

Step 3-4: requirements and priorities

Step 3: Turn needs into testable requirements

For each journey, write what the product must do as short, testable requirements: one behaviour each, with acceptance criteria someone else can check. Separate three kinds:

  • Functional: what the product does ("a dispatcher can reassign a job").
  • Non-functional: how well it does it ("the job list loads within 2 seconds").
  • Constraints: what cannot change ("data stays in the EU", "must use the client's existing login").

Link every requirement to a goal. A requirement with no goal behind it is the first candidate for "later".

Step 4: Prioritise with MoSCoW

Mark each requirement Must, Should, Could or Won't (this time). The test for a Must is blunt: would the release be useless, illegal or unsafe without it? If not, it is a Should.

Keep the Musts in proportion. The DSDM guidance from the Agile Business Consortium recommends that Must Have work stay at no more than about 60% of the effort, leaving the Shoulds and Coulds as room to absorb surprises. If almost everything is a Must, the priorities have not been set yet.

Step 5: in, out and later

This is the step that prevents most scope arguments. Take the prioritised list and sort every item into one of three columns, then write the result down as its own short section of the scope document.

In (this release) Out (not this project) Later (a known next step)
All Musts Things you decided not to build at all Shoulds and Coulds that did not fit
Shoulds that fit the budget Ideas that do not serve a goal Features waiting on a dependency or a decision
Constraints, always Work someone else owns (another team, the client) Second user types or markets

A few rules make the list useful:

  • Write the "out" column in full sentences. "No native mobile app; the web app works on mobile browsers" is clearer than "mobile: out".
  • Give "later" items a trigger, an owner and a review date. A trigger such as "after the pilot" or "once the payment provider is chosen" says when the item becomes relevant; an owner and a date make sure someone actually decides to pull it in, move it or drop it. Without them, "later" items quietly turn into expectations.
  • Name who owns anything outside the team: data migration, content, third-party contracts, user training.
  • Review the list with the decision maker line by line. Silence is not agreement.

The "out" column is the one people skip, and the one they need most when a new request arrives in week six: you can point at it and ask what should move to make room. When something new is added to "in", ask one question: which existing item moves out, or is this a change order? Log each request with its date and a rough estimate before work starts, so the conversation is about a list rather than about who remembers what.

Step 6: estimate as a range

Estimate only the "in" column, and give a range rather than a single number. Early estimates are genuinely uncertain: in Steve McConnell's Cone of Uncertainty, an estimate made at the initial concept stage can be off by up to 4x in either direction, narrowing as requirements and design are completed (Construx). A single number hides that; a range shows it.

A practical way to do it:

  1. Group the in-scope requirements into milestones that each deliver something a user can see.
  2. Estimate each milestone as low-high effort, for example in person-weeks.
  3. Write the assumptions each estimate relies on ("the dispatch system's API is documented and available in test", "the client supplies content by week 4").
  4. List the main risks and what you would do if one happens.

The assumptions are part of the estimate, not a footnote. When one turns out to be false, the estimate is expected to change, and everyone can see why.

Here is what that looks like in the public example report, for an invented project called Fieldwise: four milestones, each with a person-week range, a total of 16-22 person-weeks, and the assumptions listed right under them.

The roadmap section of the example report for the invented Fieldwise project: four milestones with status, linked requirement count, a low-high estimate in person-weeks and a target date, followed by four assumptions

Step 7: get the scope signed

The final scope statement can be short. It should contain:

  • The goals and their metrics.
  • The users and the journeys covered.
  • The in-scope requirements, or a reference to the requirements document.
  • The in, out and later list.
  • The estimate range, milestones and assumptions.
  • How changes will be handled: who can request one, who approves it, and how its cost is shown.

Ask the person who owns the budget to sign it, not only a project contact. For client work, the signed scope usually becomes the basis of the statement of work or the contract; that wording is a matter for the contract itself (and for a lawyer where needed).

Before you ask for the signature, run the scope through the discovery phase checklist: an unanswered question there is a risk you can still fix cheaply.

The last two sections of the discovery phase checklist: questions on estimates, roadmap and risks, and sign-off questions such as whether the first-release scope is agreed in writing

If you keep the scope in one place rather than across files, it is also easier to keep current. In Discovery Phase AI, for example, requirements carry their MoSCoW priority and linked goal, and the roadmap stage holds milestones with a low-high person-week estimate next to the assumptions they depend on; the example report shows the whole invented project in that form.

Disclosure and a sample

I build Discovery Phase AI, a tool aimed at the writing-and-assembling side of discovery: it drafts the early stages from the decks, documents and call transcripts you already have, and exports one report. Your team still runs the interviews, reviews every draft and makes the decisions.

If you just want to see what a finished discovery looks like, here is a complete sample report for an invented field-service app. No signup needed.

The original of this post is on our blog. Questions or corrections are welcome in the comments.

This post was drafted with AI assistance and edited by a human before publishing.

Top comments (3)

Collapse
 
scopepaid profile image
ScopePaid •

The in/out/later table is the part I'd steal for client work. I keep a running change log where every request gets logged with the date and a rough hour estimate before anyone starts work, so week six is a conversation about the list instead of a memory contest.

One tweak: give "later" items an owner and a trigger date, not just a trigger phrase, otherwise they quietly become expectations. And when something new lands in "in," I ask which existing item moves out or whether it's a change order — that one question settles most scope arguments before they start.

Collapse
 
oleksandr_tytarenko profile image
Oleksandr Tytarenko •

@scopepaid The change log with a date and a rough estimate is a great habit. “A memory contest” is exactly what week six turns into without one.

Both tweaks are good, and the first one fills a gap in the post. A trigger phrase like “after launch” or “if usage grows” has no owner, so nobody ever checks it. Each “later” item becomes something the client assumes is coming. With a name and a date, it gets an actual decision: pull it in, push the date, or drop it.

“Which item moves out, or is this a change order?” is the question I wish I’d learned to ask earlier. It makes the trade-off visible. Without it, every addition looks free until the deadline slips.

Do you keep the change log in a shared place the client can see, or only internally? I’ve gone back and forth on that. Sharing it builds trust, but it also turns every entry into a discussion.

Collapse
 
scopepaid profile image
ScopePaid •

Shared, but deliberately lightweight: one line per entry with a date, a rough hour estimate, and a status (decided or pending). Anything that would spark a whole discussion I keep internal and only surface it when it's time to make a call. That way the client sees the trail and builds trust, but the log doesn't turn into a meeting every time someone skims it.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.